-
1. Re: uniqueconstraint in ejb3.0
ciovo Oct 21, 2005 10:27 AM (in response to ruud1)I've a similar problem... In my example i try to add a row in a table using manager.persist(obj) (where obj is mapped to a table) that violate a unique constraint, and i get the same WARN and ERROR on the server console. I've tried to try/catch the manager.persist(obj) but Exception is not catched... and the remote caller catch Exception but not ConstraintViolationException, and it reports "org.jboss.tm.JBossRollbackException: Unable to commit, tx=TransactionImpl:XidImpl[FormatId=257, GlobalId=intel650/201, BranchQual=, localId=201] status=STATUS_NO_TRANSACTION; - nested throwable: (org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update)".
How to catch this kind of exception? I want to elimate the stacktrace in the server and I'd like to catch this sort of exception because I need to be informed of the error type.
Thanks! -
2. Re: uniqueconstraint in ejb3.0
dwebster Nov 13, 2005 1:04 PM (in response to ruud1)Me, too. Have yet to figure it out. Can't even find any attempt to handle basic errors in the JBoss Trailblazers...
-
3. Re: uniqueconstraint in ejb3.0
jgc195 Jan 16, 2006 10:24 AM (in response to ruud1)Did anybody have any luck with this?
-
4. Re: uniqueconstraint in ejb3.0
cyril.joui Jan 16, 2006 10:29 AM (in response to ruud1)Hello,
Did you try to add :@Column(unique=true)
? -
5. Re: uniqueconstraint in ejb3.0
jgc195 Jan 16, 2006 10:51 AM (in response to ruud1)Hi,
The problem isn't that the constraint isn't being applied - it is, and it's working fine. The problem is that we can't catch the exception gracefully.
For example:
1) Create a user named 'bob'
2) Create another user also called 'bob'
This generates an exception - which is fine. The 'Caused by' will be java.sql.SQLException: Duplicate entry 'bob' for key 2. I can catch the Exception in the Stateless Session Bean which is creating the user Entity Beans (org.hibernate.exception.ConstraintViolationException), but this doesn't stop the bubble of the Exception. I next get the following in my log:
ERROR [AssertionFailure] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
For example, If a Stateless Session Bean looks like this:public boolean addUser(String username) { try { User newUser = new User(username); em.persist(newUser); return true; } catch (Exception e) { /* Ignore exception */ return false; } }
i would expect the method to return false in the event of a duplicate key insert...and that be the end of it. But, what actually happens is a the AssertionFailure exception.
My guess is this is something to do with the underlying Hibernate session.
What I'd like to do is stop the AssertionFailure exception from occuring.
Any help or ideas would be appreciated
Thanks,
Jason -
6. Re: uniqueconstraint in ejb3.0
laboratory Jan 18, 2006 11:05 AM (in response to ruud1)same problem here! noone can solve this? i hope in a eary answer tnx ;)
-
7. Re: uniqueconstraint in ejb3.0
jonefun Jan 18, 2006 11:22 AM (in response to ruud1)To catch a constraint violation in your session bean you need to call flush() on the entity manager.
See this thread for more information :
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=71611
Cheers
Jono -
8. Re: uniqueconstraint in ejb3.0
jgc195 Jan 18, 2006 11:50 AM (in response to ruud1)Hi,
I tried your suggestion, but I get exactly the same problem. Here's my new code:public boolean addUser(String username) { try { User newUser = new User(username); em.persist(newUser); em.flush(); return true; } catch (Exception e) { /* Ignore exception */ return false; } }
Reading the other thread that you pointed us at, it seems that the only way to get around this is to catch the exception in the calling code. From what I can gather, the best way to do this is to create a new Exception class and annotate it with '@ApplicationException(rollback=true)'.
My problem remains though, the exception cannot be handled and quashed within the Session bean's 'addUser' method...is my understanding correct?
Thanks for your help,
Jason -
9. Re: uniqueconstraint in ejb3.0
jonefun Jan 18, 2006 11:55 AM (in response to ruud1)As long as the column has the unique constraint annotated and you call flush() on the entity manager that should be all you need to force the exception in your session bean class.
-
10. Re: uniqueconstraint in ejb3.0
jgc195 Jan 18, 2006 12:37 PM (in response to ruud1)Thanks for your reply.
My entity does have the relevent field annotated as unique@Column(nullable=false, unique=true) public String getUsername() { return username; } public void setUsername(String username) { this.username = username; }
and I have a em.flush() in my session bean. As I mentioned before, the Exception is caught by my session bean.org.hibernate.exception.ConstraintViolationException
but then I get:16:37:20,640 ERROR [AssertionFailure] an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session) org.hibernate.AssertionFailure: null id in com.sega.kongo.entity.user.KongoUser entry (don't flush the Session after an exception occurs)
This makes some sense to me...because the creation of the User failed, the 'id' will indeed be null. I tried to rollback the transaction (in the 'catch' block of my session beanem.getTransaction().rollback();
but that failed miserably with the following exception message: Illegal to call this method from injected, managed EntityManager
Just to make sure that this isn't a potential bug in JBoss, with which version of JBoss have you successfully applied this strategy? I'm using jboss-4.0.3SP1.
Thanks as always,
Jason -
11. Re: uniqueconstraint in ejb3.0
ruud1 Jan 19, 2006 2:28 AM (in response to ruud1)Hi,
I started this thread but unfortunatly the solution is still not presented.
Can somebody rewrite the initial example and eliminate the exception : org.hibernate.exception.ConstraintViolationException
because i want to catch a java/j2ee defined exception to make it possible to run my ear-file within every application-server. -
12. Re: uniqueconstraint in ejb3.0
jgc195 Jan 19, 2006 6:56 AM (in response to ruud1)I've done some reading, and I think it's working properly...
http://docs.jboss.org/ejb3/app-server/HibernateEntityManager/reference/en/html_single/index.html
Section 4.2.3. Exception handlingIf the EntityManager throws an exception (including any SQLException), you should immediately rollback the database transaction, call EntityManager.close() (if createEntityManager() has been called) and discard the EntityManager instance. Certain methods of EntityManager will not leave the persistence context in a consistent state. No exception thrown by an entity manager can be treated as recoverable. Ensure that the EntityManager will be closed by calling close() in a finally block. Note that a container managed entity manager will do that for you. You just have to let the RuntimeException propagate up to the container.
So it would seem that catching the exception in the calling code is the only way to go. Following this approach, then the link that Jono provided gives all the information you need, namely 1) calling em.flush and 2) creating and annotating a checked excpetion (with @ApplicationException)
http://www.jboss.com/index.html?module=bb&op=viewtopic&t=71611
Cheers,
Jason -
13. Re: uniqueconstraint in ejb3.0
ruud1 Jan 19, 2006 7:56 AM (in response to ruud1)It works that way, but as you can see in the example at the beginning of this thread (the flush and @ApplactionException) are already in place.
My problem stays : the class org.hibernate.exception.ConstraintViolationException is imported in the bean and this makes it impossible to use the bean in an ear on another application server !
Correct me if i am wrong.
Greetings
Ruud van Kersbergen -
14. Re: uniqueconstraint in ejb3.0
hoagiex Jun 14, 2006 4:18 AM (in response to ruud1)Thta won't work. This problem has been around since the birthdays of Hibernate.
Basically it comes down to this:
The exception that is throw isn't thrown back through the call-chain, but rather through the container. This exception doesn't 'land' back in your application until it reaches the starting point of the transaction, which must commonly is your Session Facade.
To this day, I haven't found a fix for this problem, but I will keep trying.
ps. Even if calling flush() were to fix the problem, it still wouldn't be the solution, since you are flushing your entire EntityManager, which can cause a problem that wasn't created in the current unique-contraint situation, but it would be caught there, giving you the false impression that a unique contraint was violated.