Hibernate ver.でJPA 2を使用しています。4.1.7.Final としての JPA 実装。明確にするために、Spring フレームワーク v. 3.1.2.RELEASE も使用しています。そして、ここに私の問題があります。
User エンティティを追加/更新するメソッドを作成しました。
@Override
@Transactional
public void saveUser(UserForm userForm) {
User user;
if (userForm.getId() == null) { // new user
user = new User();
user.setCreationDate(new Date());
entityManager.persist(user); // !!!
} else {
user = entityManager.find(User.class, userForm.getId());
}
user.setFirstName(userForm.getFirstName());
user.setLastName(userForm.getLastName());
user.setMiddleName(userForm.getMiddleName());
user.setEmail(userForm.getEmail());
user.setRole(entityManager.find(Role.class, 1));//TODO
user.setLogin(userForm.getLogin());
user.setPassword(userForm.getPassword1());
entityManager.flush();
}
ユーザーの追加をテストしています (userForm.getId() == null)。そして、上記のコードは機能せず、エラーが発生します:
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Column 'first_name' cannot be null
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1377)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1300)
at org.hibernate.ejb.AbstractEntityManagerImpl.convert(AbstractEntityManagerImpl.java:1306)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:989)
...
しかし。flush() がすべて正常に動作する前に、persist() への呼び出しを最後に移動すると、次のようになります。
@Override
@Transactional
public void saveUser(UserForm userForm) {
User user;
if (userForm.getId() == null) { // new user
user = new User();
user.setCreationDate(new Date());
} else {
user = entityManager.find(User.class, userForm.getId());
}
user.setFirstName(userForm.getFirstName());
user.setLastName(userForm.getLastName());
user.setMiddleName(userForm.getMiddleName());
user.setEmail(userForm.getEmail());
user.setRole(entityManager.find(Role.class, 1));//TODO
user.setLogin(userForm.getLogin());
user.setPassword(userForm.getPassword1());
entityManager.persist(user);// !!!
entityManager.flush();
}
何が起こるかは、最初の(問題)ケースで、ユーザーオブジェクトデータを保存しようとする場合に発生すると思いますが、実際の保存はflush()中に実行されますが(upd。間違っています。persist(で正確にSQL挿入を発行しようとします) ) 電話)。このように考えさせられるのは、デバッグしようとしたときに、正しい creation_date を内部のどこかに挿入しようとしていることがわかりましたが、他の値は null です。
しかし、私が数年前に取り組んでいた他のプロジェクトでは、これは問題なく機能したことを誓いますが、その後、MySQL の代わりに Oracle を使用し (これが理由ではないと思います)、古いバージョンのフレームワークを使用しました。
ここで何が問題になる可能性がありますか?これに影響を与えるHibernateの設定オプションがあるのでしょうか?
または、これは正しい動作であり、JPA API に対する私の誤解ですか?
アップデート。私は使用しています
@Id
@GeneratedValue
@Column(columnDefinition="INT")
private int id;
ユーザー エントリの id フィールド。mysqlのauto_incrementキーに適した生成戦略= AUTOを意味すると思います。