ConstraintValidator (JSR-303) + EJB Injection CDI (JSR-299)

0

Witam

Chciałbym przy pomocy Java Bean Validation (JSR-303) napisać validator, któy będzie sprawdzał czy podana nazwa użytkownika istnieje już bazie danych. W tym celu napisałem klasę imlementującą interfejs ConstraintValidator, która wstrzykuje EJB, pełniące rolę DAO. Wstrzykiwanie rozwiązałem poprzez CDI (JSR-299). Poniżej zamieściłem kod:

Validator:

import javax.inject.Inject;
import javax.validation.ConstraintValidatorContext;

public class UniqueUsernameValidator implements ConstraintValidator<UniqueUsername, String>
{
@Inject
private UserDataAccessObject userDataAccessObject;

         public void initialize(UniqueUsername constraintAnnotation) {}

public boolean isValid(String value, ConstraintValidatorContext context) 
{	
	return userDataAccessObject.findByUsername(value) == null;
}

}

Adnotacja UniqueUsername:

@Documented
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
@NotNull(message = "{error.required}")
@Constraint(validatedBy = UniqueUsernameValidator.class)
public @INTERFACE UniqueUsername
{
public String message() default "{error.usernameExists}";

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

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

}

UserDataAccessObject to standardowy lokalny interfejs biznesowy dla bezstanowego EJB, które wtrzykuje sobie EntityManager'a za pomocą @PersistenceContext, calość jest spięta z JSF. Zdefiniowałem także plik pusty beans.xml (na potrzeby CDI). Gdy próbuje zapisac nowego użytkownika (wypełniam formularz i klikam na submit'a) wyrzuca mi następujący błąd:

avax.validation.ValidationException: Unexpected exception during isValid call
at org.hibernate.validator.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:144)
at org.hibernate.validator.engine.ConstraintTree.validateConstraints(ConstraintTree.java:118)
at org.hibernate.validator.metadata.MetaConstraint.validateConstraint(MetaConstraint.java:121)
at org.hibernate.validator.engine.ValidatorImpl.validateValueForGroup(ValidatorImpl.java:655)
at org.hibernate.validator.engine.ValidatorImpl.validateValue(ValidatorImpl.java:591)
at org.hibernate.validator.engine.ValidatorImpl.validateValue(ValidatorImpl.java:146)
at javax.faces.validator.BeanValidator.validate(BeanValidator.java:301)
at javax.faces.component.UIInput.validateValue(UIInput.java:1127)
at javax.faces.component.UIInput.validate(UIInput.java:941)
at javax.faces.component.UIInput.executeValidate(UIInput.java:1189)
at javax.faces.component.UIInput.processValidators(UIInput.java:691)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1080)
at javax.faces.component.UIForm.processValidators(UIForm.java:243)
at javax.faces.component.UIComponentBase.processValidators(UIComponentBase.java:1080)
at javax.faces.component.UIViewRoot.processValidators(UIViewRoot.java:1180)
at com.sun.faces.lifecycle.ProcessValidationsPhase.execute(ProcessValidationsPhase.java:76)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:101)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:312)
at org.apache.catalina.core.StandardWrapper.service(StandardWrapper.java:1523)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:279)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:188)
at org.apache.catalina.core.StandardPipeline.invoke(StandardPipeline.java:641)
at com.sun.enterprise.web.WebPipeline.invoke(WebPipeline.java:97)
at com.sun.enterprise.web.PESessionLockingStandardPipeline.invoke(PESessionLockingStandardPipeline.java:85)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:185)
at org.apache.catalina.connector.CoyoteAdapter.doService(CoyoteAdapter.java:325)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:226)
at com.sun.enterprise.v3.services.impl.ContainerMapper.service(ContainerMapper.java:165)
at com.sun.grizzly.http.ProcessorTask.invokeAdapter(ProcessorTask.java:791)
at com.sun.grizzly.http.ProcessorTask.doProcess(ProcessorTask.java:693)
at com.sun.grizzly.http.ProcessorTask.process(ProcessorTask.java:954)
at com.sun.grizzly.http.DefaultProtocolFilter.execute(DefaultProtocolFilter.java:170)
at com.sun.grizzly.DefaultProtocolChain.executeProtocolFilter(DefaultProtocolChain.java:135)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:102)
at com.sun.grizzly.DefaultProtocolChain.execute(DefaultProtocolChain.java:88)
at com.sun.grizzly.http.HttpProtocolChain.execute(HttpProtocolChain.java:76)
at com.sun.grizzly.ProtocolChainContextTask.doCall(ProtocolChainContextTask.java:53)
at com.sun.grizzly.SelectionKeyContextTask.call(SelectionKeyContextTask.java:57)
at com.sun.grizzly.ContextTask.run(ContextTask.java:69)
at com.sun.grizzly.util.AbstractThreadPool$Worker.doWork(AbstractThreadPool.java:330)
at com.sun.grizzly.util.AbstractThreadPool$Worker.run(AbstractThreadPool.java:309)
at java.lang.Thread.run(Thread.java:619)
Caused by: java.lang.NullPointerException
at com.validation.impl.UniqueUsernameValidator.isValid(UniqueUsernameValidator.java:19)
at com.validation.impl.UniqueUsernameValidator.isValid(UniqueUsernameValidator.java:1)
at org.hibernate.validator.engine.ConstraintTree.validateSingleConstraint(ConstraintTree.java:141)
... 42 more

Używam Javy korporacyjnej 6 na serwerze Glassfish 3.x

Z tutoriali zamieszczonych w necie wynika że robię wszystko dobrze. Moze coś przeoczyłem. Jesli ktoś mógłby mi pomóc, byłbym wdzięczny.

Z góry dzięki

Pozdrawiam

0

Jestes pewny ze validaty wspieraja Dependency Injection? Za JSR 330:

The default ConstraintValidatorFactory provided by the Bean Validation provider implementation uses the pub-
lic no-arg constructor of the ConstraintValidator class. A custom ConstraintValidatorFactory can be
provided; for example it may benefit from dependency injection control in constraint implementations. Any con-
straint implementation relying on ConstraintValidatorFactory behaviors specific to an implementation
(dependency injection, no no-arg constructor and so on) are not considered portable, hence great care should be
given before walking that path.

Z tego wynika ze mozna sobie samemu napisac factory ktore umie wstrzykiwac, ta domyslna tego nie umie.
A nawet jesli umie, to GlassFish ma tyle bugow zwiazanych z CDI ze nie zdziwilbym sie gdyby to byl jeden z nich.

1 użytkowników online, w tym zalogowanych: 0, gości: 1