我将 JPA 2 与 Hibernate 版本一起使用。4.1.7.Final 作为 JPA 实现。我也在使用 Spring framework v. 3.1.2.RELEASE 来明确。这是我的问题。
我已经编写了一种方法来添加/更新我的用户实体。
@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();
}
我认为发生的情况是在第一种(问题)情况下,它尝试存储在持久调用时存在的用户对象数据,尽管在刷新()期间执行的实际保存(更新。错误。它试图在持久( ) 称呼)。让我这么想的原因是,当我尝试调试时,我发现它仍然尝试在内部某处插入正确的 creation_date,但其他值是空值。
但我发誓,在几年前我一直在从事的另一个项目中,这工作得很好,尽管后来我使用了 Oracle 而不是 MySQL(我不认为这是原因)和旧版本的框架。
这里可能是什么问题?也许 Hibernate 有一些配置选项会影响这个?
或者这是正确的行为和我对 JPA API 的误解?
UPD。我在用着
@Id
@GeneratedValue
@Column(columnDefinition="INT")
private int id;
用于用户条目中的 id 字段。我相信这意味着生成策略 = AUTO,这适用于 mysql auto_increment 键。