Прежде чем описать проблему, позвольте мне объяснить, что я использую Playframework 2.4.4 с Hibernate 5.0.5 и используя чистые методы JPA, т.е. , У меня нет доступа к методам «saveOrUpdate» Hibernate, но они должны использовать либо слияние, либо сохранение. Кроме того, в соответствии с последней рекомендацией playframework (когда не используется ebean) мой класс Model не расширяет класс play.db.ebean.Model.Playframework: функция слияния EntityManager JPA не работает - не использует значения переменных члена субъекта
Проблема:
Мой призыв к EntityManager.merge терпит неудачу с исключением «NULL не допускаются для столбца», хотя связанный с переменной-члена в экземпляре объекта действительно заполнен!
Детали:
- Класс; три поля, два из которых образуют составной первичный ключ.
- Существует новый экземпляр этого класса, заполненный привязкой формы Play. Я проверил содержимое экземпляра и действительно содержит значения для столбца проблемы.
- Стол пуст.
- Хотя значения заполнены, значения не поступают в инструкцию SQL, и поскольку задействован первичный ключ, этот результат, конечно, возникает в исключении [error] - org.hibernate.engine.jdbc.spi. SqlExceptionHelper - NULL не разрешено для столбца «IDTYPECODE»; SQL заявление:
Вопрос:
Тем не менее, мой объект полностью заполнен. Так почему это произошло? Согласно всем, что я прочитал, функция слияния должна успешно вставить новую несогласованную запись в этом случае! Что я сделал не так? Persist WILL работает в этом случае, но на самом деле, в моей конкретной ситуации я не могу узнать, сохранились ли эти объекты в базе данных или нет. Хотелось бы избежать поиска, чтобы проверить это существование! По моему мнению, это должно быть возможно!
Дальнейшие подробности:
Вот определение класса
@Entity
public class IdType implements Serializable
{
/**
* User specified Unique identifier.
* Both idTypeCode and idCategory are together
* a compound key, so as to ensure that the
* combination of the both can not occur more
* than once in the table.
*/
@Id
public String idTypeCode;
@Id
public IdCategory idCategory;
public String idTypeName;
}
Мой контроллер очень прост;
@Transactional
public Result updateIds()
{
IdType idType = Form.form(IdType.class).bindFromRequest().get();
System.out.println("idTypeCode is: "+idType.idTypeCode);
EntityManager em = entityManager();
em.merge(idType);
return redirect(routes.Application.index());
}
Выход консоли от попытки сохранить этот объект таким образом, заключается в следующем:
idTypeCode is: national_number
[error] - org.hibernate.engine.jdbc.spi.SqlExceptionHelper - NULL not allowed for column "IDTYPECODE"; SQL statement:
insert into IdType (idTypeName, idTypeCode, idCategory) values (?, ?, ?) [23502-187]
[error] - play.core.server.netty.PlayDefaultUpstreamHandler - Cannot invoke the action
javax.persistence.RollbackException: Error while committing the transaction
at org.hibernate.jpa.internal.TransactionImpl.commit(TransactionImpl.java:86) ~[hibernate-entitymanager-5.0.5.Final.jar:5.0.5.Final]
at play.db.jpa.DefaultJPAApi.withTransaction(DefaultJPAApi.java:142) ~[play-java-jpa_2.11-2.4.4.jar:2.4.4]
at play.db.jpa.JPA.withTransaction(JPA.java:159) ~[play-java-jpa_2.11-2.4.4.jar:2.4.4]
at play.db.jpa.TransactionalAction.call(TransactionalAction.java:16) ~[play-java-jpa_2.11-2.4.4.jar:2.4.4]
at play.core.j.JavaAction$$anonfun$7.apply(JavaAction.scala:94) ~[play_2.11-2.4.4.jar:2.4.4]
Как вы можете видеть, SQL заявление, работающий в данном случае это именно то, что я хотел бы надеяться, ибо, учитывая, что объект не существует:
insert into IdType (idTypeName, idTypeCode, idCategory) values (?, ?, ?) [23502-187]
Тем не менее, по какой-то причине, хотя я знаю, что есть значение «idTypeName» в моем объекте, он говорит мне, что:
[error] - org.hibernate.engine.jdbc.spi.SqlExceptionHelper - NULL not allowed for column "IDTYPECODE"; SQL statement:
Так почему же оно игнорирует мою явно заполненную стоимость?
Я читал в другом месте, что слияние должно работать; то есть, если объект существует в базе данных, он будет выполнять обновление, если нет, вставку. Является ли это странное поведение результатом Playframework, изменяющего нормальное поведение библиотеки JPA (в этом случае я использую Hibernate).
Любые идеи?
ОБНОВЛЕНИЕ !!!!!
ОК, наконец, настало время посмотреть дальше в этом. Кажется, это не имеет никакого отношения к игре. Я протестировал сейчас тот же самый сценарий с прямым консольным приложением JPA/Hibernate. У меня такая же проблема. Проблема возникает, как только у меня есть составной ключ (как в данном примере). Как только я удалю один из столбцов в качестве ключа, слияние будет работать. Теперь я исследую, почему это так, и как избежать проблемы (при этом мне нужна модель). Я обновлю эту проблему, как только у меня появится дополнительная информация.