自定义约束hibernate验证器中的访问会话

时间:2014-12-18 10:28:36

标签: java hibernate

我有一个问题,我已经解决但我不明白为什么。所以也许有人可以帮助我理解它。我为hibernate验证器创建了一个自定义约束。当我操作实体时,使用update,merge或saveorupdate。它总是返回堆栈跟踪溢出异常。所以我谷歌它,然后我尝试一些代码,而不是它的工作。但是我仍然想知道它为什么会起作用,以及它为什么抛出异常。

这是自定义注释的代码

@Target({METHOD, FIELD, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = UniqueIDValidator.class)
@Documented
public @interface UniqueKey {
String message() default "{validation.unique}";

     Class<?>[] groups() default {};

     Class<? extends Payload>[] payload() default {};

     /**
     * The mapped hibernate/jpa entity class
     */
     Class<?> entity();

    /**
     * The property of the entity we want to validate for uniqueness. Default name is "id"
    */
    String property() default "id";
}

这是自定义约束验证器代码

public class UniqueIDValidator implements ConstraintValidator<UniqueKey, Serializable>{
     private final static Logger LOG= Logger.getLogger(UniqueIDValidator.class);
     @Autowired
     private SessionFactory sessionFactory;
     private Class<?> entityClass;
     private String uniqueField;
     public void initialize(UniqueKey unique) {
         SpringBeanAutowiringSupport.processInjectionBasedOnCurrentContext(this);
         entityClass = unique.entity();
         uniqueField = unique.property();
     }
     @Override
     public boolean isValid(Serializable arg0, ConstraintValidatorContext arg1) {
         String query = String.format("from %s where %s = :%s ", entityClass.getName(), uniqueField, uniqueField);
         List<?> list = null;
         try{
             list = sessionFactory.getCurrentSession().createQuery(query).setParameter(uniqueField, arg0).list();   <---- This line cause the exeption      
         }catch(Exception e){
             LOG.error(e);
         }  
         return (list != null && !(list.size() > 1));
    }
}

在我跟随Here后,我尝试连接EntityManager但总是返回null,所以我在下面有这个代码,并且它有效。

@Override
public boolean isValid(Serializable arg0, ConstraintValidatorContext arg1) {        
    String query = String.format("from %s where %s = :%s ", entityClass.getName(), uniqueField, uniqueField);
    List<?> list = null;
    try{
        // below line of code make it worked
        sessionFactory.getCurrentSession().setFlushMode(FlushMode.COMMIT);
        list = sessionFactory.getCurrentSession().createQuery(query).setParameter(uniqueField, arg0).list();            
    }catch(Exception e){
        LOG.error(e);
    }finally { 
        // this is to reset the hibernate config I think
        sessionFactory.getCurrentSession().setFlushMode(FlushMode.AUTO);
    }  
    return (list != null && !(list.size() > 1));
}

例外是

java.lang.StackOverflowError at  java.util.HashMap$EntrySet.iterator(HashMap.java:1082) at  sun.reflect.annotation.AnnotationInvocationHandler.hashCodeImpl(AnnotationInvoca‌​tionHandler.java:294) 
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHa‌​ndler.java:64) 
at com.sun.proxy.$Proxy35.hashCode(Unknown Source) at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidator‌​Manager$CacheKey.createHashCode(ConstraintValidatorManager.java:326)

我想问的是: 1.为什么在我添加Flushmode.COMMIT之前它抛出stackoverflow异常? 2.此更改是否会影响其他hibernate行为,如save,persist等?

我很抱歉我的英语很差,英语不是我的母语。提前谢谢。

现在我遇到了新问题,我在更新时会评估此约束。我必须检查对象是否处于脏状态。但我不知道怎么做。

0 个答案:

没有答案