2013-10-14 93 views
0

我有我的Roo模型的驗證器。無限驗證循環

當它發現一個錯誤(返回false)時,它按預期工作。

然而,當成功時,控制器進入導致StackOverflowError無限循環:

at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:387) 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForCurrentGroup(ValidatorImpl.java:351) 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateInContext(ValidatorImpl.java:303) 
at org.hibernate.validator.internal.engine.ValidatorImpl.validate(ValidatorImpl.java:133) 
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:136) 
at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:94) 
at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:181) 
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:81) 
at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:377) 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:369) 
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:286) 
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:339) 
at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:62) 
at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1205) 
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1262) 
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101) 
at org.hibernate.ejb.QueryImpl.getSingleResult(QueryImpl.java:283) 
at com.foo.domain.validate.UniqueNameValidator.isValid(UniqueNameValidator.java:30) 
at com.foo.domain.validate.UniqueNameValidator.isValid(UniqueNameValidator.java:1) 
at org.hibernate.validator.internal.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:308) 
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:180) 
at org.hibernate.validator.internal.engine.ConstraintTree.validateConstraints(ConstraintTree.java:124) 
at org.hibernate.validator.internal.metadata.core.MetaConstraint.validateConstraint(MetaConstraint.java:86) 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraint(ValidatorImpl.java:442) 
at org.hibernate.validator.internal.engine.ValidatorImpl.validateConstraintsForDefaultGroup(ValidatorImpl.java:387) 

注意,第一行和最後一行是相同的。堆棧跟蹤在發生堆棧溢出之前重複多次。

我UniqueNameValidator看起來是這樣的:

public class UniqueNameValidator implements ConstraintValidator<UniqueFoo, Foo> { 
    public boolean isValid(Foo value, ConstraintValidatorContext context) { 
    TypedQuery<Long> q = ... // checks several conditions with other models in actual code 
    return q.getSingleResult() == 0; 
    } 
} 

我的袋鼠MVC控制器看起來是這樣的:

@RequestMapping(method = RequestMethod.POST, produces = "text/html") 
public String create(@Valid Foo foo, 
        BindingResult bindingResult, 
        Model uiModel, 
        HttpServletRequest httpServletRequest) { 
    if (bindingResult.hasErrors()) { 
     populateCreateForm(uiModel, foo); 
     return "foos/create"; 
    } 
    uiModel.asMap().clear(); 

    foo.persist(); 

    return Session.getStoredURI("/" + encodeUrlPathSegment(foo.getId().toString(), httpServletRequest)); 
} 

我的模型看起來是這樣的:

@RooJavaBean 
@RooJpaActiveRecord 
@UniqueName 
public class Foo { 
    @NotNull 
    private String parentName; 
    ... 
} 

我在做什麼錯?

回答

1

UniqueNameValidator中的查詢導致遞歸驗證。

TypedQuery<Long> q = ... 
return q.getSingleResult() == 0; 

需要是:

TypedQuery<Long> q = ... 
q.setFlushMode(FlushModeType.COMMIT); 
return q.getSingleResult() == 0;