I am getting a ERROR: duplicate key value violates unique constraint "users_pkey"
Detail: Key (userid)=(2701) already exists.
whenever i use the persist model to update my user entity.
In the code sample below: SetLoginAttempts takes in a user entity that has been queried and when i start the transaction i simply set one of the entity's fields and call persist(), then commit the transaction.
/**
* @param user
* @param attemptNumber
*/
@Transactional
public void setLoginAttempts(Users user, int attemptNumber){
user.setLoginAttempts(attemptNumber);
System.out.println(user);
}
Here is how i reference and grab the entity manager:
eFactory = Persistence.createEntityManagerFactory("persistenceUnit");
eManager = eFactory.createEntityManager();
When looking at the stack trace, i noticed that the commit actually injects an insert
Call: INSERT INTO USERS (userID, EMAIL, ISLOCKED, LOGINATTEMPTS, passwordHash, passwordSalt, USERNAME, version) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
bind => [2701, [email protected], false, 1, $shiro1$SHA-256$500000$6mqzZ/d/3BLQuJqLh1dDhQ==$NKW7Z++o/JTvf884aDWhP3Uhpyb5fTPMrm4joWnw7nI=, [B@1a8e3115, admin, 1]
What is the proper way to reference an entity manager in Spring roo, update a field and commit the changes?
Edit
I added the @Transactional to the method and the stack trace shows that this is creating the entity manager instance:
2012-03-14 23:49:15,503 ["http-bio-8080"-exec-18] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Creating new transaction with name [org.bixin.dugsi.service.UserService.setLoginAttempts]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT; ''
2012-03-14 23:49:15,503 ["http-bio-8080"-exec-18] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Opened new EntityManager [org.eclipse.persistence.internal.jpa.EntityManagerImpl@46b9979b] for JPA transaction
[EL Finer]: 2012-03-14 23:49:15.503--ServerSession(2128384958)--Thread(Thread["http-bio-8080"-exec-18,5,main])--client acquired: 1116759395
[EL Finer]: 2012-03-14 23:49:15.503--ClientSession(1116759395)--Thread(Thread["http-bio-8080"-exec-18,5,main])--acquire unit of work: 368076985
2012-03-14 23:49:15,503 ["http-bio-8080"-exec-18] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Not exposing JPA transaction [org.eclipse.persistence.internal.jpa.EntityManagerImpl@46b9979b] as JDBC transaction because JpaDialect [org.springframework.orm.jpa.DefaultJpaDialect@c595bcd] does not support JDBC Connection retrieval
Email: [email protected], Id: 2701, IsLocked: false, LoginAttempts: 2, Password: $shiro1$SHA-256$500000$6mqzZ/d/3BLQuJqLh1dDhQ==$NKW7Z++o/JTvf884aDWhP3Uhpyb5fTPMrm4joWnw7nI=, PasswordSalt: [B@1a8e3115, Roles: 0, Username: admin, Version: null
2012-03-14 23:49:15,503 ["http-bio-8080"-exec-18] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Initiating transaction commit
2012-03-14 23:49:15,503 ["http-bio-8080"-exec-18] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Committing JPA transaction on EntityManager [org.eclipse.persistence.internal.jpa.EntityManagerImpl@46b9979b]
[EL Finer]: 2012-03-14 23:49:15.503--UnitOfWork(368076985)--Thread(Thread["http-bio-8080"-exec-18,5,main])--begin unit of work commit
[EL Finer]: 2012-03-14 23:49:15.503--UnitOfWork(368076985)--Thread(Thread["http-bio-8080"-exec-18,5,main])--end unit of work commit
[EL Finer]: 2012-03-14 23:49:15.504--UnitOfWork(368076985)--Thread(Thread["http-bio-8080"-exec-18,5,main])--resume unit of work
2012-03-14 23:49:15,504 ["http-bio-8080"-exec-18] DEBUG org.springframework.orm.jpa.JpaTransactionManager - Closing JPA EntityManager [org.eclipse.persistence.internal.jpa.EntityManagerImpl@46b9979b] after transaction
2012-03-14 23:49:15,504 ["http-bio-8080"-exec-18] DEBUG org.springframework.orm.jpa.EntityManagerFactoryUtils - Closing JPA EntityManager
[EL Finer]: 2012-03-14 23:49:15.504--UnitOfWork(368076985)--Thread(Thread["http-bio-8080"-exec-18,5,main])--release unit of work
But still no updates to the DB even after refresh, why isnt the transaction closing and updating the DB?
In this example you will learn how to update an entity object in JPA. We use the EntityManager. merge() method to update an entity. This method takes the entity to be saved as the parameter and return the merged entity back as the result.
You can use Hibernate's update or JPA's merge method to associate a detached entity with a persistence context. After you've done that, Hibernate will update the database based on the entity attribute values.
In JPA, the EntityManager interface is used to allow applications to manage and search for entities in the relational database. The EntityManager is an API that manages the lifecycle of entity instances. An EntityManager object manages a set of entities that are defined by a persistence unit.
EntityManagerFactory vs EntityManagerWhile EntityManagerFactory instances are thread-safe, EntityManager instances are not. The injected JPA EntityManager behave just like an EntityManager fetched from an application server's JNDI environment, as defined by the JPA specification.
JPA exposes two methods... persist() and merge()
Persist: Persist is responsible for inserting new rows to DB and then associating the Entity with state in JPA session.
Merge: Merge takes existing Entity and updates the DB row. It also updates the state of the entity in JPA session.
I think The user already exists in your database table. In order to update the login count, you can use the merge()
method on EntityManager.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With