Сохранение прав доступа к базе данных с помощью шаблона активной записи Spring Roo

Я разрабатываю весеннее веб-приложение с использованием Spring Roo только для генерации классов персистентного слоя (само веб-приложение разрабатывается с использованием платформы ZK), используя шаблон активной записи Roo.

У меня есть простая проблема, чтобы получить сущность из БД (особенно из постоянного класса Userсоответствующая таблица названа my_user), пусть поля будут отредактированы в пользовательском интерфейсе, а затем сохраните измененную сущность в БД.

Если я все делаю правильно, в моих классах контроллеров у меня есть методы для (A) извлечения пользовательских данных, имеющих username доступно: это делается по телефону

User user = User.findUsersByUsernameEquals(username).getSingleResult()

и, кажется, работает нормально (данные правильно отображаются в пользовательском интерфейсе) и (B) сохраняет данные объекта обратно в БД. Для этого я называю метод

user.merge()

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

org.hibernate.exception.ConstraintViolationException: could not execute statement; nested exception is javax.persistence.PersistenceException:        
org.hibernate.exception.ConstraintViolationException: could not execute statement[SQL: 1062, 23000]
...
caused by:
...
com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: 
Duplicate entry '<username value>' for key '...'

Заметки:

1) User сущность как автоматически сгенерированный ключ Id. username поле (не ключевое) помечено как --unique при генерации с Roo. Если я попытаюсь восстановить схему, удалив уникальное требование на usernameэффект слияния - создание второй записи в БД (без каких-либо исключений) с тем же именем пользователя и другим значением Id (что явно не является желаемым поведением моего приложения).

2) Глядя на логи, hibernate (поставщик сохраняемости, используемый под JPA), на самом деле пытается выполнить sql INSERT заявление (я ожидал UPDATE):

[DEBUG] (org.hibernate.SQL:104) insert into my_user (address, email, enabled, firstname, password, surname, telephone, username, version) values (?, ?, ?, ?, ?, ?, ?, ?, ?)
Hibernate: insert into my_user (address, email, enabled, firstname, password, surname, telephone, username, version) values (?, ?, ?, ?, ?, ?, ?, ?, ?)

3) Если я призываю user.persist() вместо user.merge() Я получил то же исключение, что и раньше (это была просто попытка, вызов.persist() не должен быть правильным способом сохранения измененной сущности, если я правильно понял).

Я только начинаю программировать на JPA и Roo, так что я не уверен, что делаю все правильно. У меня сложилось впечатление, что проблема может быть связана с отсоединением сущности между моментом, когда я читаю данные с помощью findUsersByUsernameEquals и merge(), но это всего лишь предположение.

Заранее спасибо,

1 ответ

Решение

Я думаю, что нашел решение, благодаря этой теме: JPA Hibernate merge выполняет вставку вместо обновления

Проблема была связана с тем, что Roo автоматически добавляет version поле при создании сущностей jpa. Я заполнял свою исходную базу данных набором INSERT INTO где я не установил значения для этого поля, в результате чего оно было инициализировано с нулем.

Если я установлю это на 0 в моем INSERT INTO Скажите код работает. (вероятно, это никогда не происходит при создании непосредственно экземпляров из кода Java с persist(), который, я думаю, правильно инициализирует поле версии)

Другие вопросы по тегам