在SELECT查询中使用Hibernate ConstraintViolationException [英] Hibernate ConstraintViolationException on SELECT query
问题描述
我有一个多字段唯一约束的持久类。但定义的唯一约束对于我来说是不够的,因为在这些字段中,不相等但相似的值也是唯一的。
我实现了一个 checkUniqueConstraint
方法。
在添加和更新DAO类的方法中,我在调用 checkUniqueConstraint
之前添加或更新持久化对象。
checkUniqueConstraint
方法只是运行一个SELECT查询来找到类似于输入的对象,并且抛出一个检查Exception在哪里找到一些。
public class PersistClassDao {
public void checkUniqueConstraint(PersistClass persistObject)throws DuplicateEntityException {
/ **
*创建查询字符串,查找类似的持久对象输入参数。
** /
尝试{
PersistClass result =(PersistClass)query.uniqueResult();
if(result!= null&&(persistObject.getId()== null || persistObject.getId()!= result.getId())){
throw new DuplicateEntityException(exceptionMessage, );
}
} catch(NonUniqueResultException e){
throw new DuplicateEntityException(exceptionMessage);
$ b public long add(/ *新的persistObject * /的字段)抛出DuplicateEntityException {
//创建persistObject的transisent实例
PersistClass newObject = getPersistClass(/ * new persistObject * /的字段);
checkUniqueConstraint(newObject);
尝试{
getCurrentSession()。save(newObject);
getCurrentSession()。flush();
返回newObject.getId();
} catch(ConstraintViolationException e){
throw new DuplicateEntityException();
$我有一个transactionl服务mehod添加和另一个更新。
当我运行我的测试时,
- 首先添加2个persistObjects(通过服务方法)。
- 然后更新一个(通过服务方法)它们,以便类似于其他
- 我期望抛出DuplicatException
但是真的是一个org.hibernate.exception。 ConstraintViolationException抛出checkUniqueConstraint !!
为什么?
解决方案问题必须出现在 FlushMode 中。 Hibernate默认在执行查询之前刷新实体,请参阅 http ://docs.jboss.org/hibernate/core/3.5/javadocs/org/hibernate/FlushMode.html#AUTO 。
您必须有部分初始化新实体,将它们与会话绑定的实体相关联,然后尝试执行查询。 Hibernate会话在查询之前执行flush操作,并以ConstraintViolationException失败,这是正常的。
解决方案:
- 在整个应用程序的cfg文件中将 FlushMode 更改为 COMMIT ,
- 只修改一个会话 session.setFlushMode(FlushMode.COMMIT)或
- 通过调用query.setFlushMode(FlushMode),可以将更改的影响缩小到单个查询。 COMMIT)。
I have a Persistent Class with multi-field unique constraint on it. But defined unique constraint is not sufficient for me because on one those field non-equal but similar values are unique too.
I implement a checkUniqueConstraint
method.
In add and update methods of DAO class, I call checkUniqueConstraint
before adding or updating persist object.
checkUniqueConstraint
method just run a SELECT query to find object similar to input and throw a check Exception where find some ones.
public class PersistClassDao {
public void checkUniqueConstraint(PersistClass persistObject) throws DuplicateEntityException {
/**
* creating a query string that find persist objects similar to input parameter.
**/
try {
PersistClass result = (PersistClass) query.uniqueResult();
if(result != null && (persistObject.getId() == null || persistObject.getId() != result.getId())){
throw new DuplicateEntityException(exceptionMessage, "");
}
} catch (NonUniqueResultException e) {
throw new DuplicateEntityException(exceptionMessage);
}
}
public long add(/* field of new persistObject*/) throws DuplicateEntityException {
//creates a transisent instance of persistObject
PersistClass newObject = getPersistClass(/* field of new persistObject*/);
checkUniqueConstraint(newObject);
try {
getCurrentSession().save(newObject);
getCurrentSession().flush();
return newObject.getId();
} catch (ConstraintViolationException e) {
throw new DuplicateEntityException();
}
}
I have a transactionl service mehod for add and another for update.
When I run my test that
- First add 2 persistObjects (through service method).
- Then update one (through service method) them so that be similar to the other
- I expect that DuplicatException be thrown
But really a org.hibernate.exception. ConstraintViolationException thrown through checkUniqueConstraint!!
Why?
解决方案 The problem must be in FlushMode. Hibernate by default flushes entities before executing queries, see http://docs.jboss.org/hibernate/core/3.5/javadocs/org/hibernate/FlushMode.html#AUTO.
You must have partially initialized new entities, associated them with the session-bounded ones and now try to do the query. Hibernate session executes flush just before the query and fails with ConstraintViolationException, which is OK.
Solution:
- change FlushMode to COMMIT in cfg file for the entire application,
- modify just a single session by session.setFlushMode(FlushMode.COMMIT) or
- you can narrow the impact of the change down to the single Query by calling query.setFlushMode(FlushMode.COMMIT).
这篇关于在SELECT查询中使用Hibernate ConstraintViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!