Galera,
estou com um problema muito estranho qdo utilizo uma validação por “annotation” do Hibernate. Eu quero validar o valor único de uma coluna no banco (o Hibernate não possui esta validação) e utilizei esta implementação aqui: https://forum.hibernate.org/viewtopic.php?p=2417577 .
Exatamente como no link acima (exceto pelo nome da classe que implementa a interface), os códigos
- definição da ANNOTATION
@Target(ElementType.TYPE)
@Retention(RetentionPolicy.RUNTIME)
@ValidatorClass(UniqueImpl.class)
public @interface Unique {
/** Query string to execute to determine uniqueness. */
String hql();
String message() default "The specified field value is not unique.";
}
- implementação da INTERFACE/ANNOTATION
public class UniqueImpl implements Validator<Unique> {
private String hql;
/** The collection of named parameters in the HQL statement. */
private String[] params;
/**
* Initializes the validator instance with properties from the specified
* annotation parameters.
*
* @param parameters
* the parameters of the field to validate's Unique annotation
*/
public void initialize(Unique parameters) {
this.hql = parameters.hql();
this.params = createParameterList(this.hql);
}
/**
* Extracts the named parameters from the specified HQL statement.
*
* @param query
* the HQL statement to parse
* @return an array of all the named parameters (of the form :name) found in
* the provided string
*/
private String[] createParameterList(final String query) {
final Matcher matcher = Pattern.compile(":[^\\s]*").matcher(query);
List<String> paramList = new ArrayList<String>();
while (matcher.find()) {
paramList.add(this.hql
.substring(matcher.start() + 1, matcher.end()));
}
return paramList.toArray(new String[paramList.size()]);
}
/**
* Method to determine whether or not the value passes validation.
* <p>
*
* Validation in this case refers to a value being unique.
*
* @param value
* the value to validate for uniqueness
* @return true if the value is unique, false otherwise
*/
public boolean isValid(Object value) {
Query query = ((EntityManager) Component.getInstance("entityManager"))
.createQuery(this.hql);
Class valueClass = value.getClass();
Field field;
for (int i = 0; i < this.params.length; i++) {
try {
field = valueClass.getDeclaredField(this.params[i]);
field.setAccessible(true);
Object fieldValue = field.get(value);
query.setParameter(this.params[i],
(null != fieldValue) ? fieldValue : "");
}
catch (final NoSuchFieldException e) {
e.printStackTrace();
}
catch (final IllegalAccessException e) {
e.printStackTrace();
}
}
int size = query.getResultList().size();
System.out.println("---------------------- Result2: " + size);
return size == 0;
}
}
- Entidade para ser validada (Company.java) - o código todo pra, se alguem souber, identificar algum conflito de Annotations…
/**
* Company
*/
@Entity
@Unique(hql = "FROM Company c WHERE c.taxpayerNumber = :taxpayerNumber AND c.idCompany != :idCompany")
@Table(name = "company", schema = "public",
uniqueConstraints = @UniqueConstraint(columnNames = "taxpayer_number"))
public class Company implements java.io.Serializable {
private static final long serialVersionUID = -3271120183522777661L;
private int idCompany;
private String taxpayerNumber;
private String name;
private String tradingName;
private String address;
private Date registrationDate;
private Set<Person> persons = new HashSet<Person>(0);
public Company() {
this.registrationDate = new Date();
}
public Company(int idCompany, String taxpayerNumber, String name,
String tradingName, Date registrationDate) {
this.idCompany = idCompany;
this.taxpayerNumber = taxpayerNumber;
this.name = name;
this.tradingName = tradingName;
this.registrationDate = registrationDate;
}
public Company(int idCompany, String taxpayerNumber, String name,
String tradingName, String address, Date registrationDate,
Set<Person> persons) {
this.idCompany = idCompany;
this.taxpayerNumber = taxpayerNumber;
this.name = name;
this.tradingName = tradingName;
this.address = address;
this.registrationDate = registrationDate;
this.persons = persons;
}
@Id
@Column(name = "id_company", unique = true, nullable = false)
@SequenceGenerator(name = "company_seq", sequenceName = "company_id_company_seq")
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "company_seq")
public int getIdCompany() {
return this.idCompany;
}
public void setIdCompany(int idCompany) {
this.idCompany = idCompany;
}
@Column(name = "taxpayer_number", unique = true, nullable = false, length = 18)
@NotNullWithJqueryMask(length = 14)
@Length(max = 18)
public String getTaxpayerNumber() {
return this.taxpayerNumber;
}
public void setTaxpayerNumber(String taxpayerNumber) {
this.taxpayerNumber = taxpayerNumber;
}
@Column(name = "name", nullable = false, length = 150)
@Length(max = 150)
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
}
@Column(name = "trading_name", nullable = false, length = 150)
@Length(max = 150)
public String getTradingName() {
return this.tradingName;
}
public void setTradingName(String tradingName) {
this.tradingName = tradingName;
}
@Column(name = "address", length = 200)
@Length(max = 200)
public String getAddress() {
return this.address;
}
public void setAddress(String address) {
this.address = address;
}
@Temporal(TemporalType.DATE)
@Column(name = "registration_date", nullable = false, length = 13)
public Date getRegistrationDate() {
return this.registrationDate;
}
public void setRegistrationDate(Date registrationDate) {
this.registrationDate = registrationDate;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "company")
public Set<Person> getPersons() {
return this.persons;
}
public void setPersons(Set<Person> persons) {
this.persons = persons;
}
}
A coisa muito doida que acontece é no método isValid(…) em UniqueImpl :
- Se retorna TRUE, ele finaliza a lifeCycle e persiste os dados;
- Se retorna FALSE, é lançada a excessão abaixo, ao invés de invalidar o ciclo e retornar pra view com a msg de erro.
15:34:02,574 INFO [STDOUT] ---------------------- Result2: 1
15:34:02,574 SEVERE [application] org.hibernate.validator.InvalidStateException: validation failed for: br.com.arvus.reportbuilder.entity.Company
javax.faces.el.EvaluationException: org.hibernate.validator.InvalidStateException: validation failed for: br.com.arvus.reportbuilder.entity.Company
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
at javax.faces.component.UICommand.broadcast(UICommand.java:387)
at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: org.hibernate.validator.InvalidStateException: validation failed for: br.com.arvus.reportbuilder.entity.Company
at org.hibernate.validator.event.ValidateEventListener.validate(ValidateEventListener.java:148)
at org.hibernate.validator.event.ValidateEventListener.onPreInsert(ValidateEventListener.java:172)
at org.hibernate.action.EntityInsertAction.preInsert(EntityInsertAction.java:178)
at org.hibernate.action.EntityInsertAction.execute(EntityInsertAction.java:72)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:279)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:263)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:167)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:321)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1027)
at org.hibernate.ejb.AbstractEntityManagerImpl.flush(AbstractEntityManagerImpl.java:304)
at org.jboss.seam.persistence.EntityManagerProxy.flush(EntityManagerProxy.java:92)
at org.jboss.seam.framework.EntityHome.persist(EntityHome.java:85)
at br.com.arvus.reportbuilder.session.CompanyHome.persist(CompanyHome.java:56)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.seam.util.Reflections.invoke(Reflections.java:22)
at org.jboss.seam.intercept.RootInvocationContext.proceed(RootInvocationContext.java:32)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:56)
at org.jboss.seam.transaction.RollbackInterceptor.aroundInvoke(RollbackInterceptor.java:28)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.transaction.TransactionInterceptor$1.work(TransactionInterceptor.java:97)
at org.jboss.seam.util.Work.workInTransaction(Work.java:47)
at org.jboss.seam.transaction.TransactionInterceptor.aroundInvoke(TransactionInterceptor.java:91)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44)
at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68)
at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:107)
at org.jboss.seam.intercept.JavaBeanInterceptor.interceptInvocation(JavaBeanInterceptor.java:185)
at org.jboss.seam.intercept.JavaBeanInterceptor.invoke(JavaBeanInterceptor.java:103)
at br.com.arvus.reportbuilder.session.CompanyHome_$$_javassist_seam_3.persist(CompanyHome_$$_javassist_seam_3.java)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:335)
at org.jboss.el.util.ReflectionUtil.invokeMethod(ReflectionUtil.java:348)
at org.jboss.el.parser.AstPropertySuffix.invoke(AstPropertySuffix.java:58)
at org.jboss.el.parser.AstValue.invoke(AstValue.java:96)
at org.jboss.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:276)
at com.sun.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:68)
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
... 53 more
15:34:02,589 WARNING [lifecycle] #{companyHome.persist}: org.hibernate.validator.InvalidStateException: validation failed for: br.com.arvus.reportbuilder.entity.Company
javax.faces.FacesException: #{companyHome.persist}: org.hibernate.validator.InvalidStateException: validation failed for: br.com.arvus.reportbuilder.entity.Company
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:118)
at javax.faces.component.UICommand.broadcast(UICommand.java:387)
at org.ajax4jsf.component.AjaxViewRoot.processEvents(AjaxViewRoot.java:321)
at org.ajax4jsf.component.AjaxViewRoot.broadcastEvents(AjaxViewRoot.java:296)
at org.ajax4jsf.component.AjaxViewRoot.processPhase(AjaxViewRoot.java:253)
at org.ajax4jsf.component.AjaxViewRoot.processApplication(AjaxViewRoot.java:466)
at com.sun.faces.lifecycle.InvokeApplicationPhase.execute(InvokeApplicationPhase.java:82)
at com.sun.faces.lifecycle.Phase.doPhase(Phase.java:100)
at com.sun.faces.lifecycle.LifecycleImpl.execute(LifecycleImpl.java:118)
at javax.faces.webapp.FacesServlet.service(FacesServlet.java:265)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:83)
at org.jboss.seam.web.IdentityFilter.doFilter(IdentityFilter.java:40)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.MultipartFilter.doFilter(MultipartFilter.java:90)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.ExceptionFilter.doFilter(ExceptionFilter.java:64)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.RedirectFilter.doFilter(RedirectFilter.java:45)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.ajax4jsf.webapp.BaseXMLFilter.doXmlFilter(BaseXMLFilter.java:178)
at org.ajax4jsf.webapp.BaseFilter.handleRequest(BaseFilter.java:290)
at org.ajax4jsf.webapp.BaseFilter.processUploadsAndHandleRequest(BaseFilter.java:368)
at org.ajax4jsf.webapp.BaseFilter.doFilter(BaseFilter.java:495)
at org.jboss.seam.web.Ajax4jsfFilter.doFilter(Ajax4jsfFilter.java:56)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.LoggingFilter.doFilter(LoggingFilter.java:60)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.web.HotDeployFilter.doFilter(HotDeployFilter.java:53)
at org.jboss.seam.servlet.SeamFilter$FilterChainImpl.doFilter(SeamFilter.java:69)
at org.jboss.seam.servlet.SeamFilter.doFilter(SeamFilter.java:158)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.jboss.web.tomcat.filters.ReplyHeaderFilter.doFilter(ReplyHeaderFilter.java:96)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:235)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:235)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:191)
at org.jboss.web.tomcat.security.SecurityAssociationValve.invoke(SecurityAssociationValve.java:190)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:433)
at org.jboss.web.tomcat.security.JaccContextValve.invoke(JaccContextValve.java:92)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.process(SecurityContextEstablishmentValve.java:126)
at org.jboss.web.tomcat.security.SecurityContextEstablishmentValve.invoke(SecurityContextEstablishmentValve.java:70)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:127)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:102)
at org.jboss.web.tomcat.service.jca.CachedConnectionValve.invoke(CachedConnectionValve.java:158)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:330)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:829)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:598)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:447)
at java.lang.Thread.run(Thread.java:619)
Caused by: javax.faces.el.EvaluationException: org.hibernate.validator.InvalidStateException: validation failed for: br.com.arvus.reportbuilder.entity.Company
at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:102)
at com.sun.faces.application.ActionListenerImpl.processAction(ActionListenerImpl.java:102)
... 52 more
Alguem, pelo amor de Deus, tem alguma idéia pq isso acontece??! ?? ??
Eu utilizo o Jboss SEAM 2.2 no JbossAS 5.1, onde o projeto, algumas classes (FooList.java e FooHome.java) e visões foram geradas pelo JbossTools do eclipse.
Desde já agradeço, e muito,
CARVO.