title: False on Class-Level Constraint Validation makes Arjuna TwoPhaseCoordinator.beforeCompletion fail
body: <p>I was trying to create a somewhat more complex Cross-Field Bean-Validation in the style of <a href="https://stackoverflow.com/questions/1972933/cross-field-validation-with-hibernate-validator-jsr-303">this here</a>. What quite quickly became a problem, as soon as I returned <code>false</code> on validating the instance of my entity, that was passed to my custom validator.</p>
  
  <p>I thus created a field level constraint annotation, as described in the <a href="http://docs.jboss.org/hibernate/validator/4.0.1/reference/en/html/validator-customconstraints.html" rel="nofollow noreferrer">Hibernate tutorial</a>, but even simpler. Actually my validation was only:</p>
  
  <pre><code>@Overrides
  public bool isValid(Object value, ConstraintValidatorContext arg1){
      System.out.println("##### isValid call for example.");
      return false;
  }
  </code></pre>
  
  <p>This worked fantastically. As soon as I annotated a Field with the Annotation, any persistence-attempt was smashed and the field was marked as invalid.</p>
  
  <p>Now back to my class-level validator:</p>
  
  <pre><code>@Target({TYPE, ANNOTATION_TYPE})
  @Retention(RUNTIME)
  @Constraint(validatedBy = CrossFieldConstraintValidator.class)
  public @interface CrossFieldConstraint {
  
      String message() default "CrossFieldConstraint violation";
  
      Class&lt;?&gt;[] groups() default {};
  
      Class&lt;? extends Payload&gt;[] payload() default {};
  }
  </code></pre>
  
  <p>Not much to see here, just your standard Constraint Annotation, which defines a message, where it's validated and where it may be put.</p>
  
  <p>now when passing that to my CrossFieldConstraintValidator I recieved some overlong stacktrace. I'll paste a "slightly" shortened version, which keeps all: caused by, but removes some of the trail on it...</p>
  
  <pre class="lang-none prettyprint-override"><code> 19:04:31,806 WARN  [com.arjuna.ats.arjuna] (http-localhost-127.0.0.1-8443-3) ARJUNA012125: TwoPhaseCoordinator.beforeCompletion - failed for SynchronizationImple&lt; 0:ffffac10b1bd:32279610:5328864c:15fa, org.hibernate.engine.transaction.synchronization.internal.RegisteredSynchronization@1380d1b &gt;: 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
  </code></pre>
  
  <hr>
  
  <p>I then proceeded to reduce the complexity of the problem more and more until I got to the point, where my <code>CrossFieldConstraintValidator</code> was nothing more than:</p>
  
  <pre><code>public class CrossFieldConstraintValidator 
         implements ConstraintValidator&lt;CrossFieldConstraint, Object&gt;{
      @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;
      }
  }
  </code></pre>
  
  <p>But I still got the same error. I am running on JBoss 7.1.1.Final and using Primefaces.</p>
  
  <p>The Entity I pass is something like this:</p>
  
  <pre><code>@Entity
  @CrossFieldConstraint
  public class Project{
  
    @Id
    @GeneratedValue
    private long id;
  
    @ManyToOne
    private Customer owner;
  }
  </code></pre>
  
  <p>The persistence happens with a service class in the following manner:</p>
  
  <pre><code>@Inject
  EntityManager entityManager;
  
  public void add(Project proj, long ownerId){
     Customer managedOwner = entityManager.find(Customer.class, ownerId);
     proj.setCustomer(managerCustomer);
     entityManager.persist(proj);
  }
  </code></pre>