我有一个问题,我已经解决但我不明白为什么。所以也许有人可以帮助我理解它。我为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(AnnotationInvocationHandler.java:294)
at sun.reflect.annotation.AnnotationInvocationHandler.invoke(AnnotationInvocationHandler.java:64)
at com.sun.proxy.$Proxy35.hashCode(Unknown Source) at org.hibernate.validator.internal.engine.constraintvalidation.ConstraintValidatorManager$CacheKey.createHashCode(ConstraintValidatorManager.java:326)
我想问的是: 1.为什么在我添加Flushmode.COMMIT之前它抛出stackoverflow异常? 2.此更改是否会影响其他hibernate行为,如save,persist等?
我很抱歉我的英语很差,英语不是我的母语。提前谢谢。
现在我遇到了新问题,我在更新时会评估此约束。我必须检查对象是否处于脏状态。但我不知道怎么做。