Сохранение прав доступа к базе данных с помощью шаблона активной записи 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()
, который, я думаю, правильно инициализирует поле версии)