Kikou Kikou - 8 days ago 7
Java Question

Is there a way to force a transactional rollback when encountering an exception?

When the program encounter an exception, The RollBackOnly goes to True.

How can I "Set" this RollBack To False Even it is encountering an exception.

@Resource
protected SessionContext context;

Public void creerNewEntity(final Entity myEntity) {
try {
this.em.persist(myEntity);
this.em.flush();

} catch (final EntityExistsException e) {
System.out.println((this.context.getRollbackOnly())); // It s has a true value
throw new MyException("TODO BLABLA", e);
}
}


When the program throw this Exception "
MyException
", I change the object
myEntity
by setting for example a new Id then I call again
creerNewEntity()
.

Unfortunately, it doesn't work, I got this exception "
javax.persistence.PersistenceException: org.hibernate.HibernateException: proxy handle is no longer valid
", I think because the RollBack has a true value, How can I change the rollback to make this works ?

Thanks.

Answer

There probably isn't a simple way to do this since the whole point of the EJB design is that you don't care about such things. The first error inside of a transaction makes it invalid -> rollback. That's the rule.

If you want something special, then get yourself a database connection from the session and use plain SQL instead of EJB to modify the data. That way, you can try to INSERT a new instance and handle all exceptions yourself. When the insert succeeds, you can use EJB to load the newly created object to add it to the session.

That said, I'm not sure what you're trying to achieve with the code above. Just ignoring when you can't create a new instance in the database feels like "I don't care about quality of my product." Maybe your attempt to work around an error is just a symptom of a bad design of your application. Take a step back and consider what you're doing and why. Maybe if you told us more about the reasons why you want to ignore all errors (even the really, really deadly ones), we would be able to point out a better solution.

EDIT So you get javax.persistence.EntityExistsException which means you tried to save the same entity twice. That can mean any number of things:

  1. You loaded the bean in a different session and now you try to save it in a second one. Since the new session can't know if the bean exists, it tries to create it again.
  2. Instead of loading the bean from the session like you should, you cheated and create a new instance manually. Of course, the session manager now thinks this is a new bean.

The correct solution depends on what you need to achieve. If you modified myEntity and need to save the changes, use em.merge(). The EM will then check if the object already exists and if it does, it will do an SQL UPDATE instead of an INSERT

If you just want to give some other class a valid entity, then you need to get it from the database. If the database returns null, you need to create a new instance and persist it and then return it.

See also: JPA EntityManager: Why use persist() over merge()?

Comments