I've been googling a bit and I'm running out of time so I'm throwing this out here in the hopes that someone just knows the answer. I've got a system where I have spring transaction boundaries at the Service layer. Below that lies a dao layer. I've got bean validation on my model objects and I've wrapped the DAO's in a compile time aspectj Around aspect like this:
@Aspect
public class ValidationCollectorAspect {
@Around("daoMethods()")
public Object collectDaoMessages(ProceedingJoinPoint thisJoinPoint) throws Throwable {
try {
return thisJoinPoint.proceed();
} catch (ConstraintViolationException e) {
Set<ConstraintViolation<?>> constraintViolations = e.getConstraintViolations();
List<UserMessage> userMessages = ThreadContext.MESSAGES.get();
for (ConstraintViolation<?> constraintViolation : constraintViolations) {
userMessages.add(new UserMessage(constraintViolation.getMessage(), MessageType.VALIDATION));
}
throw new MyPersistenceException("Validation failures", e);
}
}
@Pointcut("call(public * *(..)) &&!call(* getEntityManager()) && within(com.myclient.dao.impl..*)")
public void daoMethods() {
}
}
The problem is the validation appears to happen when the transaction is committed, not prior to the save or update operation in the DAO. This means that the ConstraintViolationException from bean validation is not thrown until AFTER the service method returns and way after this join point. My evidence for this is that the stack trace does not contain any of the dao service methods. The first method for code I wrote is shown by
at com.myclient.servlet.rest.Rest.updateObjects(Rest.java:323)
But that's a method on a servlet name Rest, and the whole point is to NOT need to create join points for a whole bunch of specific methods on the various servlets in the system, and also to be able to process the Constraint violation before it's wrapped in arbitrary layers of spring exceptions.
I understand that sometimes it might be cool to validate the sum total of all the hibernate changes, just before commit, but that's not what I want. (although as second round of validation it would not be unwelcome) How can I tell hibernate validator to process the validation when I call the hibernate save or update methods in the dao, not when the transaction commits?
Here's the versions of stuff from my build:
compile 'org.hibernate:hibernate-entitymanager:4.2.2.Final'
compile 'org.hibernate:hibernate-validator:5.0.1.Final'
compile 'org.hibernate:hibernate-c3p0:4.2.2.Final'
compile 'org.springframework:spring-orm:3.2.3.RELEASE'
compile 'org.springframework:spring-context:3.2.3.RELEASE'
compile 'org.springframework:spring-web:3.2.3.RELEASE'
compile 'javax.inject:javax.inject:1'
compile 'org.aspectj:aspectjrt:1.7.3'
ajc "org.aspectj:aspectjtools:1.7.3"
Edit: One further note... I'm doing all this under JPA, so I'd prefer a non-hibernate specific solution if one exists.