This week's book giveaway is in the Agile and other Processes forum. We're giving away four copies of The Mikado Method and have Ola Ellnestam and Daniel Brolund on-line! See this thread for details.
After years of using iBatis I'm giving Hibernate a shot. My problem is that I'm not able to figure out how to persist an object which contains a list of other objects which are containing a back reference.
In my small little test-application I have an object called CD and an object called Track. Each CD should contain a list of tracks (one-to-many) and each Track should contain a back reference to the CD object to which it belongs to.
After trying out a few examples which I found on the internet and reading hours the documentation I'm desparated because I can't get it work.
Here's what I've got so far:
My trivial database schema contains only two tables:
My CD-object:
My track-object:
My test-application:
My hibernate.cfg.xml:
And the HibernateUtil-class which I copied from somewhere:
If I insert some data manually in the database the loading of the objects works perfectly. I can load a CD and the tracks are automatically loaded as well, just as expected.
If I try to save a CD-object with only one track included in the list it ALSO works as expected. Both objects are persisted and Hibernate sets the correct foreign-key (the field cdId in table track). But as soon as there are more objects in my list, I encounter a NonUniqueObjectException (Exception in thread "main" org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session).
I understood (I guess) that the problem is that my CD-object which I associate in the newCD()-method (via track.setCd(cd);) with a track is not unique in the hibernate-session.
Due to the fact that none of those objects exists in the database I can't load them from the database into the hibernate-session. I also tried to play around with evict() and merge() and also trying out a hell lot of annotation-combinations but none of them worked.
So how is this solved in general? Do I have to persist first the CD-object, load it again and then persist the Track-objects?
Sorry for this lengthy post but this really bugs me since days and I'm having the feeling is just small thing I don't see yet. And I don't know if the annotations are completly wrong or if the newCD()-method has to look differently. So, any hints for solving this problem are really really appreciated.
How cool, it works. Thanks a lot. Even though I was not able yet to implement the lazy-loading, but I guess I have to read a bit more documentation for that.
But I still have a question though: if the HibernateSingleton class is not needed anymore and calling just sessionFactory.getCurrentSession() is considered best-practice now, where should I instantiate the sessionFactory object? Should it be instantiated in the constructor of each class, where I need access to the database? Or what's considered best-practice?