User.java
@Entity
@Table(name = "User", uniqueConstraints = @UniqueConstraint(columnNames = { "emailAddress" }) )
public class User {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long userId;
private String emailAddress;
}
UserDAO.java
@Repository("UserDAO")
@Transactional
public class UserDAO {
@PersistenceContext
private EntityManager entityManager;
public String insert(User user) {
try {
entityManager.persist(user);
} catch (PersistenceException e) {
if (e.getCause() != null && e.getCause().getClass() == ConstraintViolationException.class) {
try {
insertedUserId = getIdByEmail(user.getEmailAddress());
} catch (Exception exception) {
//some error handling
}
}
}
}
private long getIdByEmail(String emailAddress) {
Query query = entityManager
.createQuery(
"FROM User WHERE emailAddress = :emailAddress")
.setParameter("emailAddress", emailAddress);
User user = (User) query.getSingleResult();
return user.getUserId();
}
}
我正在尝试将记录插入到用户表中,如果电子邮件地址(这是一个唯一列)已经存在,我想获取现有记录而不是插入新记录。现在,我想首先插入然后尝试捕获异常以找到记录。但是当我这样做时,即使在查找查询的catch子句中,我也会得到以下ConstraintViolationError。
javax.persistence.PersistenceException:org.hibernate.exception.ConstraintViolationException:无法执行语句
引起:org.h2.jdbc.JdbcSQLException:唯一索引或主键违规:“ON PUBLIC.USER(EMAILADDRESS)VALUES('abc_fgh@aol.com',1)”; SQL语句: 插入User(emailAddress,UserId)值(?,?)
答案 0 :(得分:0)
在实际情况中,我建议您先检查电子邮件是否已经存在。如果不存在则继续存在。
编辑1:如果您的目的是保存用户,那么实际上作为第二个选项,我会使用merge(user)
代替persist(user)
。
答案 1 :(得分:0)
如@manish所述,您首先需要清除entityManager,但随后可能会出现以下错误。
org.springframework.transaction.TransactionSystemException:无法提交JPA事务;嵌套异常是javax.persistence.RollbackException:事务标记为rollbackOnly
要解决此错误,只需在代码中添加以下行。 (original answer)
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
所以我的案例中的try块最终看起来像 -
try {
entityManager.clear();
insertedUserId = getIdByEmail(user.getEmailAddress());
TransactionAspectSupport.currentTransactionStatus().setRollbackOnly();
}