在SELECT查询中使用Hibernate ConstraintViolationException [英] Hibernate ConstraintViolationException on SELECT query

查看:125
本文介绍了在SELECT查询中使用Hibernate ConstraintViolationException的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个多字段唯一约束的持久类。但定义的唯一约束对于我来说是不够的,因为在这些字段中,不相等但相似的值也是唯一的。

我实现了一个 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失败,这是正常的。



解决方案:


  1. 在整个应用程序的cfg文件中将 FlushMode 更改为 COMMIT
  2. 只修改一个会话 session.setFlushMode(FlushMode.COMMIT)

  3. 通过调用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:

  1. change FlushMode to COMMIT in cfg file for the entire application,
  2. modify just a single session by session.setFlushMode(FlushMode.COMMIT) or
  3. you can narrow the impact of the change down to the single Query by calling query.setFlushMode(FlushMode.COMMIT).

这篇关于在SELECT查询中使用Hibernate ConstraintViolationException的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆