0

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.

Aruna
  • 11,959
  • 3
  • 28
  • 42
Kikou
  • 1,895
  • 4
  • 20
  • 32
  • going to guess that this is a stateless bean, how are you calling it? – Kalpesh Soni Sep 29 '14 at 14:56
  • It s a Stateful Bean. – Kikou Sep 29 '14 at 15:02
  • I specify for the EntityManager : @PersistenceContext(unitName = "sicb-tracabilite-business", type = PersistenceContextType.EXTENDED, properties = @PersistenceProperty(name = "org.hibernate.flushMode", value = "MANUAL")) protected EntityManager em; – Kikou Sep 29 '14 at 15:03
  • where are you calling creerNewEntity from? my understanding is context.setRollbackOnly() is not done by jpa, or by simply throwing exceptions – Kalpesh Soni Sep 29 '14 at 15:05
  • "creerNewEntity" is in a Class B, Class A calls this Method "creerNewEntity" , when an exception occurs , the object myEntity is modified then Class A calls again the method "creerNewEntity". I want to know how can i change the context.getRollbackOnly() to False to avoid this exception proxy handle is no longer valid". – Kikou Sep 29 '14 at 15:17
  • do you see @Stateless annotation on your classes? they are not simple classes, they are ejbs, you need to find out where its being set, you cant set it to false – Kalpesh Soni Sep 29 '14 at 15:20
  • Yes i see @Stateless in the Class B, i tried to add there lines to ejb-jar.xml . javax.persistence.EntityExistsException false – Kikou Sep 29 '14 at 15:28
  • But it doesn't work ... , When the exception occurs it s being set to true, i don t know how can i find exactly where this boolean can be set. – Kikou Sep 29 '14 at 15:29
  • @Kikou: What exception do you get and why do you get it? – Aaron Digulla Sep 30 '14 at 12:36
  • @AaronDigulla "Caused by: org.hibernate.HibernateException: proxy handle is no longer valid" – Kikou Oct 02 '14 at 07:52

2 Answers2

2

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()?

Community
  • 1
  • 1
Aaron Digulla
  • 321,842
  • 108
  • 597
  • 820
0

EntityExistsException is PersistenceException

when jpa throws it, ejb CMT is marked for rollback

http://piotrnowicki.com/2013/03/jpa-and-cmt-why-catching-persistence-exception-is-not-enough/

as aaron suggested, you could use merge()

you can also contain transaction boundary by using RequiresNew

@TransactionAttribute(REQUIRES_NEW)

http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html

Kalpesh Soni
  • 6,879
  • 2
  • 56
  • 59
  • I tried by using "@TransactionAttribute(REQUIRES_NEW)" above my method , but it doesn't work i got an "Caused by: org.hibernate.HibernateException: proxy handle is no longer valid", i ll follow comments made by Aeron. thxs – Kikou Oct 02 '14 at 07:52
  • @Kikou: http://stackoverflow.com/questions/14621801/hibernateexception-proxy-handle-is-no-longer-valid-after-database-violation-err – Aaron Digulla Oct 02 '14 at 08:00