我正在使用JPA 2與Hibernate版本。 4.1.7。最終作爲JPA實施。我也使用Spring框架v 3.1.2.RELEASE來清楚。這是我的問題。在persist()之後但在flush()之前更改JPA實體不起作用
我寫了一個方法來添加/更新我的用戶實體。
@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)
...
不過。如果我提出呼籲刷新之前,堅持()到最後()一切工作正常:
@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,但其他值是空值。
但是我發誓在幾年前我一直在工作的其他項目中,這工作得很好,儘管之後我使用了Oracle而不是MySQL(我不認爲這是原因),而且舊版本的框架。
這裏有什麼問題?也許有一些Hibernate的配置選項影響這個?
或者這是正確的行爲和我對JPA API的誤解?
UPD。我正在使用
@Id
@GeneratedValue
@Column(columnDefinition="INT")
private int id;
對於User entiry中的id字段。我相信這意味着生成策略= AUTO,適用於mysql auto_increment鍵。
聽起來這可能是使用IDENTITY進行PK生成的問題。這是在用什麼? –
我同意,如果身份證號是身份,則需要立即插入。所以如果可能的話切換到Sequence或TableGenerator。如果你不能,那麼修改過的代碼是正確的,但我會爲persist()調用添加空檢查以避免級聯檢查。 –
@SteveEbersole請在我的帖子末尾查看用戶實體的id字段的更新內容。我認爲在MySQL自動的情況下意味着與IDENTITY相同? – Xonix