Pencils Down

This weblog is about my experiences in software development

You may have recieved an exception in Hibernate like:

org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session…..

This is likely caused by your code doing something like:

session.get()

object.setSomething(value)

session.update()

The session.update() call is attempting to attach an object to the Hibernate session.  This is done by the object id.  If you already have an object with the same id associated with the session (i.e. maintained by Hibernate) you get this error.

You have two choices:

1) Don’t call update on the object.  It is already being maintained by Hibernate.  There is no need to do so.  A later flush() will push any changes recorded in the session to the database.

2) If you can not tell if the object is associated with the session (likely in a long user scenario) call merge() instead.  Merge() takes the instance passed and merges it with any object of the same id associated with the session.  Note, if you plan on using the object again you must use the object returned by the call to merge().  The instance object passed to merge will not be updated.

Someone I know has been working on a death march project.  Management has refused to listen to reason.  Expectation of producing many thousands of lines of code per developer per week.  Team members attempting to jump ship before the death bell tolls.  Team members (developers) forced to sit through grueling team status meetings (in the light of these absurd delivery dates).  Really a very illogical situation.

Then I talked to a manager at another company.  The manager thinks they are ‘just’ setting up the subcontractor on the project to take a fall.  The upper management view of the project is that everything is rosy, on-time, on-budget, happy people.  But the bad subcontractor is not producing on time, budget, quality level per contract.  Yes, technically, the sub has been amiss.  Guess where all the fingers will be pointing when the delivery time slides on by without anything to show?  Once the sub is replaced then everything can be re-scheduled, budgeted, aligned, etc… 

I wonder how many times you can do that before upper management figures out where the problem really is?

The column referenced in the jspx file,

<f:facet name="header">
<ice:commandSortHeader
columnName="DEF"
arrow="true" >
<ice:outputLabel value="D-E-F" />
</ice:commandSortHeader>
</f:facet>

must much the column name in the backing bean,

xtable = new CheckBoxTable();
...
xtable.setColumnNames(new String[] { "ABC", "DEF"});

You must specify a column width for this to work:

... style="width:20px; text-align:center"...

Our team lead just hired another contractor from the same agency I am working through.  The contractor went through the interview rounds (full-time’s only) including the team lead and group lead.

Per the team lead the developer has lots of experience with Java, JSF, SOA, etc…  All the stuff we need on the team

The guy talks, a lot.  This is just a personality trait that irks me.  So, maybe he’s ok anyway.

Then I overhear the conversations he’s having with other developers (see talks a lot above) and some of the questions he has asked me:

  • When a screen (from the functional spec) has multiple checkboxes does that mean the user can select multiple items?
  • Similar when a screen has multiple radio buttons does that mean the user can select only one?
  • Do I need the JDK installed to compile the application?
  • Are all of the user actions affecting the database?

I guess the worst part is I bet he is getting the same hourly rate (or better) than I am.

I work at a large defense contractor.  There are two levels of shareware licensing that need to be addressed for any product that is used:

1) Will the product be used in the field, in a production environment?

2) Will the product be used on the corporate LAN?

Any new product has to go through a rigorous review by legal staff to review the exact license involved in a product.  They are looking for the clause that says “We own your company after 12 days of use”.  Surprisingly, there are some open licenses that have such clauses.  Pretty gutsy – just count on coders not actually reading the legaleeze.

Use on the LAN means the product must also be reviewed for security breaches.  While a defense contractor has real security levels that conform to government standards, I think this is a reasonable test for any corporate tool.  Again, some products fail the security test by either including silliness (such as Google toolbar poking back at google.com on a regular basis) or outright virus/spam.

Use in production means the software will reside on a defense product in the field.  Whole new levels of pain to evaluate the product for holes.  Not surprisingly, there is a lot of Not Invented Here coding that goes on just to avoid such a review.

After much searching around the Internet I have come to the conclusion that Hibernate really doesn’t support self-referencing tables. The typical example is something like this table:

Table Category
---------------
categoryId int
name varchar(50)
parent int

In this example the Hibernate code would be something like:

Category parent = ...
Category child = ...
child.setParent(parent)
dao.create(child);
//this does not appear to actually do anything in a self-referencing table
parent.getChildren().add(child);
dao.saveOrUpdate(parent);
session.flush();

//and then later on

Category category = categoryDao.something();
for(Category child:category.getChildren()) {
  //do something with each child
}

Notes:

  • Since the reference is in the same table, the above add() to the parent children does nothing.
  • The setParent() call is just setting the parent column directly in the Category object – no database action is taking place.
  • Calls to getChildren() are doing a simple query unlike other getObject ORM calls in Hibernate
  • Calls to getParent() are also doing abnormal ORM calls

All of the above code ‘works’. It just doesn’t work like anything else really in Hibernate.

In our application we have the typical hierarchical object organization that is reflected in the data store.  This fits nicely into a relational database.  Being a modern shop (surprising given the industry – defense) we use Hibernate for the ORM.  Unfortunately most developers, while somewhat familiar with Hibernate and SQL, have very little experience using HQL.

A typical problem would be list all the level 3 objects in the system.  So, you might find code like:

Set<Level3Id,Level3> hash = new HashSet<Level3Id,Level3>(); 
Set<TopLevel> topLevels = dao.findAll();
for(TopLevel top:topLevels) {
    Set<Level2> level2s = top.getLevel2s();
    for(Level2 level2:level2s) {
        Set<Level3> level3s = level2.getLevel3s();
        for(Level3 level3:level3s) {
            hash.put(level3.id, level3);
        }
    }
}

where the developer is constructing a HashSet to produce a unique list of level 3 objects.  This is a simple example, there are many use cases where we traverse much lower into the object graph using some complicated tests (WHERE clauses).

The alternative HQL is trivial in comparison and the performance improvement is astounding (remember due to lazy loading each of the objects above would have to be materialized even though we never really wanted them in the first place):


List<Level3> level3s = session
        .createQuery("select distinct level3 from Level3 as level3")
        .list();

I guess the message is to try and think about the underlying SQL database that you have available.  While Hibernate obscures access to the underlying database it normally exposes all of the functionality present in the SQL into HQL in some manner.  So, if you could do something neat in SQL chances are you can do the same neat access in HQL.

IceFaces Rocks!

No comments

IceFaces is a Java AJAX framework (http://icefaces.org).  Open-source.  Through it’s live connectivity to the DOM on the client ALL interactions are performed in sequence to a back-end supporting beans.

IceFaces has all the built-ins you would expect to be able to build a RIA app.  The best part is it works and even better: the tutorials on the site work!  There are so many open source frameworks out there with very little documentation.  More typically the x.org site supporting your open source framework has limited, theoretical documentation – think of Hibernate or Spring – both excellent frameworks, but very sparse documentation on how to do regular, everyday things.  So, you end up poking around on the network and typically find several leads that are just wrong.

Such a pleasure to use a tool that you don’t have to waste time on redeveloping the wheel every day.

Expecting to see something about snow, Yahoo Weather reported “Unknown Precipitation” for my area. 

 unknown1.JPG