I’m using JPA through the Play Framework.
I’m checking to see if a User object is cached, and if so I retrieve it and merge() it such that I can update fields and save the changes later:
user = (User) Cache.get("user-auth-" + sessionAuthToken);
if (user != null) {
user = user.merge(); // I believe this is the same as EntityManager.merge()
}
However when I do this I get the following error:
PersistenceException occured :
org.hibernate.exception.ConstraintViolationException:
could not insert: [models.User]
...
Caused by: com.mysql.jdbc.exceptions.jdbc4.
MySQLIntegrityConstraintViolationException:
Duplicate entry '1235411688335416533' for key 'authToken'
It seems like its trying to insert a new user, even though this user should be, and is already in the database. Why would merge() do that?
Or perhaps I’m going about this entirely the wrong way – advice would be appreciated.
I believe your problem is the way Play manages the JPA environment (and transactions).
Once you receive a request the framework immediately creates the JPA manager and a transaction. From that moment onwards all your Model entities are automatically linked to the manager.
Play facilitates working with this model in 2 ways:
By running “merge” you are trying to add to the Manager an entity which is already there, which causes the unique key exception. If you just load the entity from the cache, you will be able to modify and call save() once done, and it will work.