Meaningless Drivel is fun!*
The moose likes Object Relational Mapping and the fly likes org.hibernate.NonUniqueObjectException at second request Big Moose Saloon
  Search | Java FAQ | Recent Topics | Flagged Topics | Hot Topics | Zero Replies
Register / Login


Win a copy of Java 8 in Action this week in the Java 8 forum!
JavaRanch » Java Forums » Databases » Object Relational Mapping
Bookmark "org.hibernate.NonUniqueObjectException at second request" Watch "org.hibernate.NonUniqueObjectException at second request" New topic
Author

org.hibernate.NonUniqueObjectException at second request

Pete Bearmen
Greenhorn

Joined: Aug 15, 2012
Posts: 3

Hi,

In a hobby project I'm currently doing to teach myself Hibernate and Spring MVC, I have an import option for movies from TMDb.
During this import I create new actors (when not available yet) and finally movie itself.

The strange thing is that the first time I import a movie, everything works as expected but when I want to import a new movie after clicking around in the application, I got the following exception:

I've set OpenSessionInViewFilter to use a SingleSession due to cascading issues, could that be interfering with this functionality?

As this is my first project using Hibernate and Spring MVC, I don't know where to start debugging this issue or which information I can provide to shed some more light on the issue.
Any help is highly appreciated.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1632
    
    7

What kind of cascading issues?

I am not a fan of the OpenSessionInViewFilter and indeed it is considered an anti-pattern by many these days.

Quoting from this site:
http://www.realsolve.co.uk/site/tech/orm-performance.php

Open Session In View should be regarded as an anti-pattern; not only because it breaks the encapsulation of data access from the web tier, but because it allows for inefficient data access if not used sparingly. Reliance on Open Session in View can easily result in large number of SQL selects being executed from the web tier, a reappearance of the N+1 Selects problem. If used, the Open Session In View should be considered a last resort, with resulting data access in the web tier considered a bug in the application. Do not place too much reliance on the Open Session in View pattern. Use it only as a last resort to avoid more embarrassing user interface bugs.


This blog gives some ideas of alternatives:
http://www.javacodegeeks.com/2011/10/avoid-lazy-jpa-collections.html

One other option that is not mentioned (many are not a fan of this either) is to map the necessary information to a DTO to send to the view layer. Libraries like Dozer can be used to map domain to dto and vice versa. Now I am not suggesting this for every use case but if you run into a situation where the previous links suggestions do not work than certainly I find it preferable to holding the session open.

My suggestion is to get rid of the OpenSessionInView filter and address the underlying cause of the ensuing LazyInitializationExceptions that will likely occur.

That said onto your original issue:

Somewhere you are probably are trying to saveOrUpdate some newly created object and the id is already present in the persistence context. Persistent ids are required to be unique within the context. You can either find the entity causing the violation and evict it from the cache or you can make use of merge.



[How To Ask Questions][Read before you PM me]
Pete Bearmen
Greenhorn

Joined: Aug 15, 2012
Posts: 3

Hi Bill,

Thanks for you answer, this did get rid of the exception, however now the "first" movie is partially overwritten by the second one, which does not seem to be created itself.
Is there a way to remove all current objects from a session before (or after) processing a new import?
What surprised me was that I needed to make the changes in a file which did not show up in the stacktrace, but I guess that has something to do with the AOP part.

About the SessionInView part. I was having issues with retrieving and especially updating lazy loaded entities (as it is a hobby project, it has been a while since I've tackled that issue, so I'm not exactly sure). It happened before I started working on the import part.
Due to my domain model, I would rather not fetch all relations eagerly, but I guess that would be a different thing I need to check out when I've solved this.
Bill Gorder
Bartender

Joined: Mar 07, 2010
Posts: 1632
    
    7

Thanks for you answer, this did get rid of the exception, however now the "first" movie is partially overwritten by the second one, which does not seem to be created itself.


Not sure I am following why this is happening exactly if they have an id. Are you sure your cascade rules are set up properly?

Is there a way to remove all current objects from a session ?


Yes. session.clear() but be careful with that one. session.evict will evict just one object from the session.

Due to my domain model, I would rather not fetch all relations eagerly,


If you read the link again there are paged queries which make more sense when you have large amounts of data that you don't want eagerly loaded but only a portion of them for the UI.


I would definitely revisit the use of OSIV. It is a pay me now or pay me later kind of scenario, but somewhere a long the way it will bite you.

Pete Bearmen
Greenhorn

Joined: Aug 15, 2012
Posts: 3

After reading the code to look for a place to test the session.evict(), I found a piece of line which might be causing the issue and sure enough it fixed the issue.

It turned out I was using a class variable which was filled during the import, however the variable was only initialized during the class initialization, which obvious isn't thread safe. Probably a beginners mistake.
When initializing the variable before starting the import routine fixed the issue.

So now it's up to fixing the OSIV.

Thanks for your pointer about the session.evict(). Without it I doubt I would have found the issue.
 
I agree. Here's the link: http://aspose.com/file-tools
 
subject: org.hibernate.NonUniqueObjectException at second request
 
Similar Threads
hibernate 1-many error
many side of one to many not being populated
What is "object is not an instance of declaring class" error in hibernate?
java.lang.OutOfMemoryError: Java heap space
Caught a NonUnique Exception while adding more rows to the table.