[英]JPA2 unique constraint: do I really need to flush?
我有一个DAO,需要捕获唯一的约束异常。 为此,唯一可行的解决方案是在持久化之后刷新我的EntityManager。 只有这样,我才能进入catch块,在其中必须过滤掉异常。 而且,我的DAO方法需要包装在事务中(REQUIRES_NEW),否则我将遇到RollBackException。
难道我做错了什么?
try {
em.persist(myObject);
em.flush();
} catch (PersistenceException ex) {
if (ex.getCause() != null) {
String cause = ex.getCause().toString();
if (cause != null) {
if (cause.contains("org.hibernate.exception.ConstraintViolationException")) {
logger
.error("org.hibernate.exception.ConstraintViolationException: possible unique constraint failure on name");
throw ex;
}
}
}
}
难道我做错了什么?
EntityManager#persist()
不会触发立即插入(除非您使用的是IDENTITY
策略)。 因此,如果您想将内存中的更改实际写入数据库并有机会捕获违反约束的情况,则必须“手动” flush()
(尽管这样做并不能严格保证任何事情,但可以对数据库进行配置使用延迟约束 )。
换句话说,您正在做的就是IMO正确的方法。
我有一个上面带有@Transactional的服务方法(必需),称为addNewObject()。 在这种方法中,可能会发生一些异常,从而引发异常(从而回滚事务)。 这些调用之一是对DAO方法addObject的调用。 由于唯一的约束,这可能会失败。 现在,如果执行刷新操作,则在没有唯一违例的情况下该对象将被保留。 但是,服务中可能仍然存在其他导致该方法引发异常的事物。
我认为您在混淆flush
和commit
。 如果在addObject
外部出现问题并引发了不可恢复的异常(但在同一事务内),则将回滚整个事务,包括与persist()
调用相对应的INSERT
语句。 总结一下, flush
!= commit
。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.