Original: https://www.toocruel.net/jpa-validate/problem introduced
Spring data JPA, which uses the validate checksum, is directly added to the entity class to be persisted, and is not validated with a dto for convenience and simplicity, but some checksums only need to be verified at the controller level, and are not required for validation when persisted. Because I declared him @transient, the following user class:
@Entity public
class User {
/**
* User name
/@NotBlank (message = "User name cannot be empty")
private String Username;
/**
* Password
/private String password;
/**
* Role ID
*
/@NotEmpty (message = "Role ID cannot be empty")
@Transient
private long[] roleids;
/**
* All roles of user * * *
@ManyToMany (cascade = Cascadetype.detach)
@JoinTable (name = "User_role_ Relation ", Joincolumns = @JoinColumn (name =" UserId "), Inversejoincolumns = @JoinColumn (name =" Roleid "))
@ Jsonignoreproperties ("users")
private set<role> roles = new hashset<> ();
//... Omitting gets and sets
}
Where the Roleids attribute is transient, indicating that it does not persist, I use it just to verify when Controller receives form form submission, checksum by depositing roles attribute, There is no need to validate on persistence (but the JPA specification, or hibernate, will validate all attributes including transient when persisted). Error recurrence
Execute Userrepository.save (new User ()), Error:
Javax.validation.ConstraintViolationException:Validation failed for classes [Net.toocruel.iqismart.entity.User] During persist time for groups [Javax.validation.groups.Default,] List of constraint violations:[constraintviolation Impl{interpolatedmessage= ' role ID cannot be empty ', Propertypath=roleids, Rootbeanclass=class Net.toocruel.iqismart.entity.User, Messagetemplate= ' role ID cannot be empty '}] at Org.hibernate.cfg.beanvalidation.BeanValidationEventListener.validate ( beanvalidationeventlistener.java:138) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.cfg.beanvalidation.BeanValidationEventListener.onPreInsert (beanvalidationeventlistener.java:78) ~ [Hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.action.internal.EntityIdentityInsertAction.preInsert (entityidentityinsertaction.java:197) ~[ Hibernate-core-5.0.12.final.jar:5.0.12.final] At Org.hibernate.action.internal.EntityIdentityInsertAction.execute (entityidentityinsertaction.java:75) ~[ hibernate-core-5.0.12.fiNal.jar:5.0.12.final] at Org.hibernate.engine.spi.ActionQueue.execute (actionqueue.java:619) ~[ Hibernate-core-5.0.12.final.jar:5.0.12.final] At Org.hibernate.engine.spi.ActionQueue.addResolvedEntityInsertAction (actionqueue.java:273) ~[ Hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.engine.spi.ActionQueue.addInsertAction ( actionqueue.java:254) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.engine.spi.ActionQueue.addAction (actionqueue.java:299) ~[hibernate-core-5.0.12.final.jar:5.0.12. Final] at Org.hibernate.event.internal.AbstractSaveEventListener.addInsertAction (Abstractsaveeventlistener.java : 317) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.event.internal.AbstractSaveEventListener.performSaveOrReplicate (Abstractsaveeventlistener.java : 272) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.event.internal.AbstractSaveEventListener.performSave (abstractsaveeventlistener.java:178) ~[ hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.event.internal.AbstractSaveEventListener.saveWithGeneratedId ( abstractsaveeventlistener.java:109) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.jpa.event.internal.core.JpaPersistEventListener.saveWithGeneratedId (Jpapersisteventlistener.java :) ~[hibernate-entitymanager-5.0.12.final.jar:5.0.12.final] at Org.hibernate.event.internal.DefaultPersistEventListener.entityIsTransient (Defaultpersisteventlistener.java : 189) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.event.internal.DefaultPersistEventListener.onPersist (defaultpersisteventlistener.java:132) ~[ Hibernate-core-5.0.12.final.jar:5.0.12.final] At Org.hibernate.event.internal.DefaultPersistEventListener.onPersist (defaultpersisteventlistener.java:58) ~[ Hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.internal.SessionImpl.firePersist (Sessionimpl.java : 775) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hiBernate.internal.SessionImpl.persist (sessionimpl.java:748) ~[hibernate-core-5.0.12.final.jar:5.0.12.final] at Org.hibernate.internal.SessionImpl.persist (sessionimpl.java:753) ~[hibernate-core-5.0.12.final.jar:5.0.12.final ] at Org.hibernate.jpa.spi.AbstractEntityManagerImpl.persist (abstractentitymanagerimpl.java:1146) ~[ Hibernate-entitymanager-5.0.12.final.jar:5.0.12.final] at Sun.reflect.GeneratedMethodAccessor190.invoke (Unknown Source) ~[na:na] at Sun.reflect.DelegatingMethodAccessorImpl.invoke (delegatingmethodaccessorimpl.java:43) ~[na : 1.8.0_131] at Java.lang.reflect.Method.invoke (method.java:498) ~[na:1.8.0_131] at Org.springframework.orm.jpa.Sha Redentitymanagercreator$sharedentitymanagerinvocationhandler.invoke (sharedentitymanagercreator.java:298) ~[ Spring-orm-4.3.10.release.jar:4.3.10.release] at Com.sun.proxy. $Proxy 145.persist (Unknown Source) ~[na:na] at Org.s Pringframework.data.jpa.repository.support.SimpleJpaRepository.save (Simplejparepository.java:508) ~[spring-data-jpa-1.11.6.release.jar:na] at Sun.reflect.NativeMethodAccessorImpl.invoke0 (Native method) ~[ NA:1.8.0_131] at Sun.reflect.NativeMethodAccessorImpl.invoke (nativemethodaccessorimpl.java:62) ~[na:1.8.0_131] at Sun.reflect.DelegatingMethodAccessorImpl.invoke (delegatingmethodaccessorimpl.java:43) ~[na:1.8.0_131] at Java.lang.reflect.Method.invoke (method.java:498) ~[na:1.8.0_131] at org.springframework.data.repository.core.support.repositoryfactorysupport$ Queryexecutormethodinterceptor.executemethodon (repositoryfactorysupport.java:504) ~[ Spring-data-commons-1.13.6.release.jar:na] At org.springframework.data.repository.core.support.repositoryfactorysupport$ Queryexecutormethodinterceptor.doinvoke (repositoryfactorysupport.java:489) ~[ Spring-data-commons-1.13.6.release.jar:na] At org.springframework.data.repository.core.support.repositoryfactorysupport$ Queryexecutormethodinterceptor.invoke (repositoryfactorysupport.java:461) ~[spring-data-commons-1.13.6.release.jar:na] at Org.springframework.aop.framework.ReflectiveMethodInvocation.proceed ( reflectivemethodinvocation.java:179) ~[spring-aop-4.3.10.release.jar:4.3.10.release] at Org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke ( defaultmethodinvokingmethodinterceptor.java:56) ~[spring-data-commons-1.13.6.release.jar:na] ...
Solutions
From the above critical error message: Validation failed for classes [Net.toocruel.iqismart.entity.User] during persist time for groups [ Javax.validation.groups.Default,] You can see that, although the @transient annotation was added to Roleids, JPA was still checked and found a groups:[ Javax.validation.groups.Default,].
Originally, JPA Validate is able to group checksum, default has a group default, to validate this group when persisted. When not specified is the default, for example, Roleids @notempty (message = "Role ID cannot be empty") does not specify groups, which is the default group, will be validated when persisted.
Thus, there is an idea that the Roleids validation group is set to another group instead of using the default, which seems to be feasible.
Then, modify the checksum annotation for user roleids:
@NotEmpty (message = "Role ID cannot be empty", groups = Controllergroup.class)
@Transient
private long[] roleids;
Added groups = Controllergroup.class, where Controllergroup is free to create a new class or interface.
... Test...
As expected, the perfect solution.