java - 类级约束验证错误使 Arjuna TwoPhaseCoordinator.beforeCompletion 失败

标签 java hibernate validation primefaces

我试图以 this here 的风格创建一个更复杂的跨域 Bean 验证.当我在验证我的实体实例时返回 false 时,问题很快就变成了一个问题,它被传递给了我的自定义 validator 。

因此,我创建了一个字段级约束注释,如 Hibernate tutorial 中所述,但更简单。实际上我的验证只是:

@Overrides
public bool isValid(Object value, ConstraintValidatorContext arg1){
    System.out.println("##### isValid call for example.");
    return false;
}

这非常有效。一旦我用注释对字段进行注释,任何持久性尝试都会被粉碎,该字段被标记为无效。

现在回到我的类级 validator :

@Target({TYPE, ANNOTATION_TYPE})
@Retention(RUNTIME)
@Constraint(validatedBy = CrossFieldConstraintValidator.class)
public @interface CrossFieldConstraint {

    String message() default "CrossFieldConstraint violation";

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

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

这里没什么可看的,只有你的标准约束注解,它定义了一条消息,它被验证的地方以及它可能被放置的地方。

现在,当将它传递给我的 CrossFieldConstraintValidator 时,我收到了一些超长的堆栈跟踪。我将粘贴一个“略微”缩短的版本,它保留了所有:引起的,但删除了它的一些踪迹......

 19:04:31,806 WARN  [com.arjuna.ats.arjuna] (http-localhost-127.0.0.1-8443-3) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple< 0:ffffac10b1bd:32279610:5328864c:15fa, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@1380d1b >: javax.persistence.PersistenceException: error during managed flush
    at org.hibernate.ejb.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1486) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:109) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93)
    at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:164)
    at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165)
    at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:117)
    at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:92) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:232) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
    at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:106) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
**Caused by:** javax.validation.ConstraintViolationException: Validation failed for classes [company.crm.model.Project] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='CrossFieldConstraint violation', propertyPath=, rootBeanClass=class company.crm.model.Project, messageTemplate='CrossFieldConstraint violation'}
]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:159) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:94) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:175) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:73) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:264) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:186) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:326) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:52) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1081) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.internal.SessionImpl.managedFlush(SessionImpl.java:315) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:104) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    ... 88 more

**19:04:31,861 ERROR** [org.jboss.ejb3.invocation] (http-localhost-127.0.0.1-8443-3) JBAS014134: EJB Invocation failed on component ProjectServiceBean for method public abstract void company.crm.services.ProjectService.addProject(long,company.crm.model.Project) throws javax.transaction.TransactionRolledbackException,javax.persistence.OptimisticLockException: javax.ejb.EJBTransactionRolledbackException: Transaction rolled back
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.handleEndTransactionException(CMTTxInterceptor.java:115) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:95) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.invokeInOurTx(CMTTxInterceptor.java:232) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.required(CMTTxInterceptor.java:304) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.processInvocation(CMTTxInterceptor.java:190) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
    at org.jboss.as.ejb3.component.interceptors.CurrentInvocationContextInterceptor.processInvocation(CurrentInvocationContextInterceptor.java:41) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
    at org.jboss.as.ejb3.security.AuthorizationInterceptor.processInvocation(AuthorizationInterceptor.java:106) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
    at org.jboss.as.ejb3.security.SecurityContextInterceptor.processInvocation(SecurityContextInterceptor.java:76) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
    at org.jboss.as.ejb3.component.interceptors.LoggingInterceptor.processInvocation(LoggingInterceptor.java:59) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    at org.jboss.invocation.InterceptorContext.proceed(InterceptorContext.java:288) [jboss-invocation-1.1.1.Final.jar:1.1.1.Final]
**Caused by:** javax.transaction.RollbackException: ARJUNA016053: Could not commit transaction.
    at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1177)
    at com.arjuna.ats.internal.jta.transaction.arjunacore.BaseTransaction.commit(BaseTransaction.java:117)
    at com.arjuna.ats.jbossatx.BaseTransactionManagerDelegate.commit(BaseTransactionManagerDelegate.java:75)
    at org.jboss.as.ejb3.tx.CMTTxInterceptor.endTransaction(CMTTxInterceptor.java:92) [jboss-as-ejb3-7.1.1.Final.jar:7.1.1.Final]
    ... 79 more
**Caused by:** javax.persistence.PersistenceException: error during managed flush
    at org.hibernate.ejb.AbstractEntityManagerImpl$CallbackExceptionMapperImpl.mapManagedFlushFailure(AbstractEntityManagerImpl.java:1486) [hibernate-entitymanager-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.transaction.synchronization.internal.SynchronizationCallbackCoordinatorImpl.beforeCompletion(SynchronizationCallbackCoordinatorImpl.java:109) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization.beforeCompletion(RegisteredSynchronization.java:53) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at com.arjuna.ats.internal.jta.resources.arjunacore.SynchronizationImple.beforeCompletion(SynchronizationImple.java:76)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.beforeCompletion(TwoPhaseCoordinator.java:273)
    at com.arjuna.ats.arjuna.coordinator.TwoPhaseCoordinator.end(TwoPhaseCoordinator.java:93)
    at com.arjuna.ats.arjuna.AtomicAction.commit(AtomicAction.java:164)
    at com.arjuna.ats.internal.jta.transaction.arjunacore.TransactionImple.commitAndDisassociate(TransactionImple.java:1165)
    ... 82 more
**Caused by:** javax.validation.ConstraintViolationException: Validation failed for classes [company.crm.model.Project] during persist time for groups [javax.validation.groups.Default, ]
List of constraint violations:[
    ConstraintViolationImpl{interpolatedMessage='CrossFieldConstraint violation', propertyPath=, rootBeanClass=class comapany.crm.model.Project, messageTemplate='CrossFieldConstraint violation'}
]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate(BeanValidationEventListener.java:159) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert(BeanValidationEventListener.java:94) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.action.internal.EntityInsertAction.preInsert(EntityInsertAction.java:175) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:73) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    at org.hibernate.engine.spi.ActionQueue.execute(ActionQueue.java:272) [hibernate-core-4.0.1.Final.jar:4.0.1.Final]
    ... 88 more

然后我开始越来越多地降低问题的复杂性,直到我到达那个地步,我的 CrossFieldConstraintValidator 只不过是:

public class CrossFieldConstraintValidator 
       implements ConstraintValidator<CrossFieldConstraint, Object>{
    @Override
    public void initialize(final CrossFieldConstraint annotation) {

    }

    @Override
    public boolean isValid(Object value, ConstraintValidatorContext validatorContext) {
    try{
        System.out.println("### isValid - " + value + "  " + validatorContext.toString());

        return false;       
    }catch(Exception logIt){
        System.out.println("Validation Failed with Exception: " +  logIt.toString());
        System.out.println("ValidatorContext: "+ validatorContext.toString());
        return false;
    }
}

但是我还是报了同样的错误。我在 JBoss 7.1.1.Final 上运行并使用 Primefaces。

我传递的实体是这样的:

@Entity
@CrossFieldConstraint
public class Project{

  @Id
  @GeneratedValue
  private long id;

  @ManyToOne
  private Customer owner;
}

持久化以下列方式发生在服务类中:

@Inject
EntityManager entityManager;

public void add(Project proj, long ownerId){
   Customer managedOwner = entityManager.find(Customer.class, ownerId);
   proj.setCustomer(managerCustomer);
   entityManager.persist(proj);
}

最佳答案

我决定忽略来自 Arjuna 的警告,现在改为捕获 EJBTransactionRolledBackException。缺少的部分是我需要从我使用的 Controller 中的 View 停止延迟。

public boolean processSave(){
   boolean success = true;
   try{
      //persistence operation via service class
   }
   catch(OptimisticLockException e){
      success = false;
      //add a faces message
   }
   catch(EJBTransactionRolledbackException e){
      success = false;
      //add another faces message
   }
   return success;
}

作为一个小信息,这是用于保存 View 操作的代码:

/**
* Triggers the save process as business logic and uses the result to determine
* what to return
* @return Navigation rule as String depending on the outcome of the save process
*/
public String save() {
   return processSave() ? navigationRuleSuccess : navigationRuleFailure;
}

关于java - 类级约束验证错误使 Arjuna TwoPhaseCoordinator.beforeCompletion 失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/22542155/

相关文章:

java - 如何在java的 Play Framework 中使用属性文件?

java - 如何在 DataFormatter 中编辑模式?

SWT 中的 Java 编程

java - 为什么 Hibernate 延迟加载在 Kotlin 中表现不同?

php - 在 CodeIgniter 中提交后显示表单成功

java - 蛇游戏(java)中的流畅动画?

java - 如何在javax约束验证中进行OR?

hibernate - jhipster - 禁用 hibernate 二级缓存

同一页面上的 PHP 表单验证提前显示

如果与数据验证一起使用,Excel 计数每次都为 0