JPA EntityManager persist () causes an object to be disabled even if an error has been thrown

Hi, I have a simple DAO with the function below.

public element createElement(Element e){ em.persist(e); em.flush(); return e; } 

The Entity table has a unique constraint for the pair (type, value), and I have a test below:

  public void testCreateElement() throws DataAccessException { // Start with empty Element table Element e = new Element(); e.setType(myType.OTHER); e.setValue("1"); dao.createElement(e); e = new Element(); e.setType(MyType.OTHER); e.setValue("1"); try{ // this should violate unique constraint of database. dao.createElement(e); } catch (Exception ex) { System.out.println(ex); } e.setValue("2"); try{ // I expect this to work as there is no element with these values. dao.createElement(e); } catch (Exception ex) { System.out.println(ex); } } 

My first error caught happens as I expect, since I know that I am violating the restriction, the second attempt / catch should not produce an error as far as I know, but it is so that I get it

 javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.mypackage.Element 

Thus, it seems that calling persist () on "e", although it was not saved, caused hibernation to be considered a separate object.

This is annoying because these functions are used by the JSF interface, which deals with the exception of ConstraintViolation, but deliberately holds the object so that the user can change one of the fields and try again, and they receive an individual object error.

Is this behavior a hibernation bug because I don’t think it should actually do this? Is there a way around this at the DAO level so that perseverance does not work out: I consider my object as disconnected if it is not really saved?

Hi,

Glen x

+6
source share
1 answer

The exception thrown by Hibernate is not restored. The only thing you should do when such an exception occurs is to roll back the transaction and close the session. The state of the session (and its entities) after such an exception is unstable.

If you want to keep the element instance intact, use merge() rather than persist() , or clone the element before saving it.

Note that an exception is expected, because when Hibernate saves and deletes an object, it starts by generating an identifier and assigning an identifier to the object, and then inserts a row that raises the exception. Thus, after an exception, the object has an assigned identifier and, therefore, is considered a sleeping object by Hibernate. You can try resetting the identifier to zero and see if it works, but I would prefer to clone an object before or using merge.

+3
source

Source: https://habr.com/ru/post/909286/


All Articles