-
1. Re: NonUniqueObjectException and EntityManager
blabno Jan 23, 2008 10:41 AM (in response to blabno)org.hibernate.NonUniqueObjectException: a different object with the same identifier value was already associated with the session
What throws that exception ? Hibernate or SEAM ? Cause i don't understand which session is metioned in quoted exception. -
2. Re: NonUniqueObjectException and EntityManager
pmuir Jan 23, 2008 12:27 PM (in response to blabno)Hibernate. You try to insert a duplicate entity into the database
-
3. Re: NonUniqueObjectException and EntityManager
blabno Jan 23, 2008 2:51 PM (in response to blabno)Abrakadabra !
I have stateful CountryCreatorBean, that has a reference to stateless LocationBean. When CountryCreatorBean.addCountry() is called then in the body of that method LocationBean.addCountry(country) is called. Country variable is injected into CountryCreatorBean by the SEAM, by the way.
It is responsibility of LocationBean, who plays role of location manager, to check if entity already exists in DB. If such a country already exists then some exception should be thrown by LocationBean.
Now is the fun part. At first I've decided to use org.hibernate.NonUniqueObjectException, since it fits the purpose perfectly. Of course in CountryCreatorBean.addCountry method I prepaired try/catch for such an ocasion. But guess what ! Transaction gets rolled back and exception is not caught, and web page gets filled with stack trace.
After a while I figured that in stead of org.hibernate.NonUniqueObjectException the javax.ejb.EJBTransactionRolledbackException gets to try/catch block.
Remember to read stack trace carefully ! By the way, what do you think about such approach to move persistance to stateless bean ? I chose this way to write business logic independently from web-framework.@Stateful @Scope(ScopeType.SESSION) @Name("countryCreator") public class CountryCreatorBean implements CountryCreatorLocal { @In(create = true) private Country country; @EJB private LocationLocal locationBean; public void addCountry() { try { locationBean.add(country); } catch (javax.ejb.EJBTransactionRolledbackException exc) { System.out.println("RuntimeException caught !"+exc); FacesMessages.instance().add("#{messages.countryAlreadyExists}"); } } @Remove public void destroy() { } }
@Stateless public class LocationBean implements LocationLocal { @PersistenceContext private EntityManager em; public void add(Country country) throws NonUniqueObjectException { if( em.find(Country.class,country.getId()) == null ) em.persist(country); else throw new NonUniqueObjectException(country.getId(),Country.class.getCanonicalName()); } }
And one more thing, nobody noticed stupid condition from previous postif( em.find(Country.class,country.getId()) != null ) //this triggers exception em.persist(country);
-
4. Re: NonUniqueObjectException and EntityManager
pmuir Jan 24, 2008 11:11 AM (in response to blabno)Well, given Seam enables you to write stateful web apps, I wouldn't choose the stateless path.