An exploration of the joys and frustrations when programming with Microsoft .NET. Taken with the perspective of working in a faith-based ministry, striving to release children from poverty in Jesus' name.

Eerie…

Posted 3.29.08 in Uncategorized

I keep seeing this ad when I go to SourceForge and other tech sites. Seems like the ads are talking directly to me! :)

wi_spy_300x250.jpg

Problems With NHibernate

Posted 1.13.08 in Uncategorized

In our latest project, our team made use of NHibernate to act as an ORM (Object-Relational Mapper) and to handle all of our data access work.

In the current phase that we are working on, we’re running into a problem. We can’t get NHibernate to delete a child object in a collection on a parent.

Here’s the basic situation:

We have a Proposal, which has a collection of ProposalMilestones. The ProposalMilestone has a reference to the parent Proposal, as well as a reference to the Milestone that it refers to.

When trying to remove a ProposalMilestone from the collection and flushing the session, NHibernate throws a StaleObjectException.

Here are images of the class diagram for this section and the database schema that applies:

NHSample NHSampleDatabase-NoNotify

Nothing special about either one. The relationships are as would be expected. 

Here are the related mapping files:

Proposal.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="CIV.Entities" assembly="NHSample" default-access="nosetter.camelcase" default-lazy="false">
    <class name="CIV.Entities.Proposal, NHSample" table="Proposal">
        <id name="Id" column="ID">
            <generator class="guid.comb" />
        </id>
        <version name="Version" column="Version" type="CIV.Entities.Timestamp, NHSample" generated="always" />
        <component name="Audit" class="CIV.Entities.Audit, NHSample">
            <property name="CreatedBy" column="CreatedBy"/>
            <property name="CreatedOn" column="CreatedOn" />
            <property name="ModifiedBy" column="ModifiedBy" />
            <property name="ModifiedOn" column="ModifiedOn" />
        </component>

        <property name="Code" column="Code" />
        <property name="Description" column="Description" />
        <property name="Name" column="Name" />
        <property name="ProposedStartDate" column="ProposedStartDate" />

        <bag name="Milestones" table="ProposalMilestone" inverse="true" cascade="all">
            <key column="ProposalID" />
            <one-to-many class="CIV.Entities.ProposalMilestone, NHSample" />
        </bag>
    </class>
</hibernate-mapping>

ProposalMilestone.hbm.xml

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" namespace="CIV.Entities" assembly="NHSample" default-access="nosetter.camelcase" default-lazy="false">
    <class name="CIV.Entities.ProposalMilestone" table="ProposalMilestone">
        <id name="Id" column="ID" unsaved-value="00000000-0000-0000-0000-000000000000">
            <generator class="guid.comb" />
        </id>
        <version name="Version" column="Version" type="CIV.Entities.Timestamp, NHSample" generated="always" />
        <component name="Audit" class="CIV.Entities.Audit, NHSample">
            <property name="CreatedBy" column="CreatedBy"/>
            <property name="CreatedOn" column="CreatedOn" />
            <property name="ModifiedBy" column="ModifiedBy" />
            <property name="ModifiedOn" column="ModifiedOn" />
        </component>
        <property name="OriginalDueDate" column="OriginalDueDate" type="DateTime" />
        <many-to-one name="Milestone" column="MilestoneID" class="CIV.Entities.Milestone, NHSample"/>
        <many-to-one name="Proposal" column="ProposalID" not-null="true" class="CIV.Entities.Proposal, NHSample" />
        <bag name="Notifications" inverse="true" cascade="all">
            <key column="ProposalMilestoneID" />
            <one-to-many class="CIV.Entities.Notification, NHSample" />
        </bag>
    </class>
</hibernate-mapping>

Milestone

<?xml version="1.0" encoding="utf-8" ?>
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="NHSample"  namespace="CIV.Entities" default-access="nosetter.camelcase" default-lazy="false">
    <class name="CIV.Entities.Milestone, NHSample" table="Milestone">
        <id name="Id" column="ID">
            <generator class="guid.comb"/>
        </id>
        <version name="Version" column="Version" type="CIV.Entities.Timestamp, NHSample" generated="always" />
        <component name="Audit" class="CIV.Entities.Audit, NHSample">
            <property name="CreatedBy" column="CreatedBy" type="String" />
            <property name="CreatedOn" column="CreatedOn" type="DateTime" />
            <property name="ModifiedBy" column="ModifiedBy" type="String" />
            <property name="ModifiedOn" column="ModifiedOn" type="DateTime" />
        </component>
        <property name="Name" column="Name" type="String" not-null="true" />
        <property name="Code" column="Code" type="String" not-null="true" />
        <property name="Description" column="Description" type="String" />

    </class>
</hibernate-mapping>

Any suggestions would be greatly appreciated.

As a side note, I think my relations expressed in the mapping could be better. ProposalMilestone is being treated as an entity right now, but there is no reason (unless NHibernate requires it for the relationships) that it needs to be. I believe Milestone is a value object, but again, it’s being treated as an entity.

Suggestions here would also be appreciated.

Updated (3.29.08)

I did get this problem solved: The final thing that worked for me was putting the optimistic-lock=”false” tag on the collection declaration (Proposal). This avoided updating the Proposal before the collection of ProposalMilestones was updated, which was causing my stale object error.

Making my wife happy

Posted 1.6.08 in Uncategorized

We’re both doing the Biggest Loser Million Pound Match-up Challenge. She has a blog for both of us to keep track in it. We have to have an official page on MSN Spaces, but Spaces sucks and doesn’t let two people show participation, so she’s just using one off of her domain.

See here: http://www.crayonsetc.com/betterme/

State of the world today

Posted 9.3.07 in Uncategorized

http://www.michaelrighi.com/2007/09/01/arrested-at-circuit-city

This is an example of things going terribly wrong. More people need to be aware of their civil liberties and rights, and be willing to assert them in appropriate ways.

Further discussion:

What’s a Solutions Architect?

Posted 5.27.07 in Uncategorized

New and Notable 167: “Jon Flanders and I (Sam Gentile) were talking over dinner last night about back in the day he and I as COM programmers could keep most of our known universe in your head. Today the pace is so furious that you have to keep WCF, WF, .NET Framework, Silverlight, Atlas, BizTalk Server and many others in your head such that a Solution Architect who digests all this stuff and picks the ‘right’ way to go makes a heck of a lot of sense these days.”

(Via CodeBetter.Com.)

Saw this posted last week-ish, and wanted to put in a few cents worth of bytes.

At Compassion, several of the Sr. Software Developers (who really do have a bent towards design and architecture) have been working at a grassroots level to create a Solutions Architect role. We’ve gotten a little traction from management on it, primarily by casting it as an intra-team communication tool.

In our workplace, development is highly focused on the project. Anything that is done is funded through a project, and the project is what moves in new technology. This would be OK (sort of, but that’s another day) if there was an in-place framework, or standards, or infrastructure or something. But there isn’t. We’re trying to define strategy, infrastructure and business value all at the same time, all in the same project.

If that sounds hard, you’re right. The project is focused on time and money. As in, right now for as little as possible. But strategy, infrastructure and framework need to be able to grow, adapt and evolve. We don’t have anyone (let alone a team) that is the owner of the base level stuff. And we see the outcome of that all over the place. Each app is different; different base technology is used, typically based on the whims of either the Sr. Developer or the Architecture Office, depending on who has been to the latest marketing buzz.

We are gradually moving in the right direction. We’ve gotten the overall strategy laid down in the past couple of months. Now it’s a matter of matching appropriate technology to the strategy. For now, that’s SharePoint at the base of it all, but there are some serious questions hanging over parts of that plan.

Where does the Solution Architect come in? They are tasked to take a step back from daily development, and find the big picture that can be lost in day-to-day activities, especially as separate teams work on functionality that could be used by other groups.

It’s hard, but it’s worth it. We will wind up with a consistent framework to build in, something where the basics don’t have to be rebuilt for each project. It’s not going to be easy, but there was never a promise of that.

← Previous Posts

About

This is a collection of the thoughts and ideas of a software developer and solutions architect with Compassion International. Topics of interest include software architecture, design patterns, software factories, team dynamics and the art of computer programming.

Meet Kenneth Scott

Categories

  • No categories

Through him then let us continually offer up a sacrifice of praise to God, that is, the fruit of lips that acknowledge his name. (Hebrews 13:15)

Copyright © 2007 – 2008, Kenneth Scott.