Обновите Entity с помощью EntityManager JPA EclipseLink - PullRequest
5 голосов
/ 15 марта 2012

Я получаю ERROR: duplicate key value violates unique constraint "users_pkey" Detail: Key (userid)=(2701) already exists. всякий раз, когда использую постоянную модель для обновления своей пользовательской сущности.

В приведенном ниже примере кода: SetLoginAttempts принимает запрашиваемую пользовательскую сущность и когда я запускаю транзакциюя просто устанавливаю одно из полей сущности и вызываю persist (), а затем фиксирую транзакцию.

/**
* @param user
* @param attemptNumber
*/
@Transactional
public void setLoginAttempts(Users user, int attemptNumber){         
    user.setLoginAttempts(attemptNumber);
    System.out.println(user);
}

Вот как я ссылаюсь на менеджер сущностей:

eFactory = Persistence.createEntityManagerFactory("persistenceUnit");
eManager = eFactory.createEntityManager();

Просматривая трассировку стека, я заметил, что при фиксации фактически вставляется вставка

Call: INSERT INTO USERS (userID, EMAIL, ISLOCKED, LOGINATTEMPTS, passwordHash, passwordSalt, USERNAME, version) VALUES (?, ?, ?, ?, ?, ?, ?, ?)
bind => [2701, admin@d.com, false, 1, $shiro1$SHA-256$500000$6mqzZ/d/3BLQuJqLh1dDhQ==$NKW7Z++o/JTvf884aDWhP3Uhpyb5fTPMrm4joWnw7nI=, [B@1a8e3115, admin, 1]

Как правильно ссылаться на менеджера сущностей в Spring roo, обновлять поле и фиксировать изменения?

Редактировать

Я добавил @Transactionalк методу, и трассировка стека показывает, что это создает экземпляр диспетчера сущностей:

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: admin@d.com, 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

Но все еще нет обновлений в БД даже после обновления, почему транзакция не закрывает и не обновляет БД?

Ответы [ 3 ]

16 голосов
/ 15 марта 2012

JPA предоставляет два метода ... persist () и merge ()

Persist: Persist отвечает за вставку новых строк в БД, а затем связывает сущность с состоянием в сеансе JPA.

Слияние: Слияние берет существующую сущность и обновляет строку БД. Он также обновляет состояние объекта в сеансе JPA.

Я думаю, что пользователь уже существует в вашей таблице базы данных. Чтобы обновить счетчик входа, вы можете использовать метод merge() в EntityManager.

2 голосов
/ 11 декабря 2015

Если ни один из упомянутых вариантов не работает, попробуйте (отрегулировав, так как это относится к моему коду):

            Query query = entityManager.createQuery("UPDATE User x SET x.activated = 1 "+ "WHERE username=:usernameParam ");
            query.setParameter("usernameParam", ""+user.username);
            query.executeUpdate();
0 голосов
/ 15 марта 2012

EntityManager.persist () используется для создания нового бина сущности.

Создание нового бина сущности включает вставку новой строки в базу данных.

Youиспользуйте EntityManager.merge (), чтобы обновить уже существующий компонент.

Вызов EntityManager.merge () обновляет базу данных, чтобы отразить изменения, внесенные в отсоединенный объектbean.

Если ваш компонент управления данными не отсоединен, нет необходимости вызывать merge ().

Если ваш пользовательский компонент не отсоединен, вы можете просто изменить егосвойства путем вызова методов, таких как setLoginAttempts () .

EntityManager и контейнер обновят базу данных автоматически (когда транзакция будет зафиксирована).

...