8
8
import java .util .HashSet ;
9
9
import java .util .Map ;
10
10
import java .util .Set ;
11
- import java .util .concurrent .ConcurrentHashMap ;
12
11
12
+ import org .hibernate .SessionFactory ;
13
+ import org .hibernate .SessionFactoryObserver ;
13
14
import org .hibernate .boot .internal .ClassLoaderAccessImpl ;
14
15
import org .hibernate .boot .registry .classloading .spi .ClassLoaderService ;
15
16
import org .hibernate .engine .spi .SessionFactoryImplementor ;
31
32
32
33
import jakarta .validation .ConstraintViolation ;
33
34
import jakarta .validation .ConstraintViolationException ;
34
- import jakarta .validation .TraversableResolver ;
35
35
import jakarta .validation .Validator ;
36
36
import jakarta .validation .ValidatorFactory ;
37
37
38
- import static jakarta .validation .Validation .buildDefaultValidatorFactory ;
39
38
import static org .hibernate .internal .util .NullnessUtil .castNonNull ;
40
39
import static org .hibernate .internal .util .collections .CollectionHelper .setOfSize ;
41
40
47
46
*/
48
47
//FIXME review exception model
49
48
public class BeanValidationEventListener
50
- implements PreInsertEventListener , PreUpdateEventListener , PreDeleteEventListener , PreUpsertEventListener , PreCollectionUpdateEventListener {
49
+ implements PreInsertEventListener , PreUpdateEventListener , PreDeleteEventListener , PreUpsertEventListener , PreCollectionUpdateEventListener ,
50
+ SessionFactoryObserver {
51
51
52
52
private static final CoreMessageLogger LOG = Logger .getMessageLogger (
53
53
MethodHandles .lookup (),
54
54
CoreMessageLogger .class ,
55
55
BeanValidationEventListener .class .getName ()
56
56
);
57
57
58
- private ValidatorFactory factory ;
59
- private final ConcurrentHashMap < EntityPersister , Set < String >> associationsPerEntityPersister = new ConcurrentHashMap <>() ;
58
+ private HibernateTraversableResolver traversableResolver ;
59
+ private Validator validator ;
60
60
private GroupsPerOperation groupsPerOperation ;
61
- boolean initialized ;
62
-
63
- /**
64
- * Constructor used in an environment where validator factory is injected (JPA2).
65
- *
66
- * @param factory The {@code ValidatorFactory} to use to create {@code Validator} instance(s)
67
- * @param settings Configured properties
68
- */
69
- public BeanValidationEventListener (
70
- ValidatorFactory factory , Map <String ,Object > settings , ClassLoaderService classLoaderService ) {
71
- init ( factory , settings , classLoaderService );
72
- }
73
61
74
- public void initialize (Map <String ,Object > settings , ClassLoaderService classLoaderService ) {
75
- if ( !initialized ) {
76
- init ( buildDefaultValidatorFactory (), settings , classLoaderService );
77
- }
62
+ public BeanValidationEventListener (
63
+ ValidatorFactory factory , Map <String , Object > settings , ClassLoaderService classLoaderService ) {
64
+ traversableResolver = new HibernateTraversableResolver ();
65
+ validator = factory .usingContext ()
66
+ .traversableResolver ( traversableResolver )
67
+ .getValidator ();
68
+ groupsPerOperation = GroupsPerOperation .from ( settings , new ClassLoaderAccessImpl ( classLoaderService ) );
78
69
}
79
70
80
- private void init (ValidatorFactory factory , Map <String ,Object > settings , ClassLoaderService classLoaderService ) {
81
- this .factory = factory ;
82
- groupsPerOperation = GroupsPerOperation .from ( settings , new ClassLoaderAccessImpl ( classLoaderService ) );
83
- initialized = true ;
71
+ @ Override
72
+ public void sessionFactoryCreated (SessionFactory factory ) {
73
+ SessionFactoryImplementor implementor = factory .unwrap ( SessionFactoryImplementor .class );
74
+ implementor
75
+ .getMappingMetamodel ()
76
+ .forEachEntityDescriptor ( entityPersister -> traversableResolver .addPersister ( entityPersister , implementor ) );
84
77
}
85
78
86
79
public boolean onPreInsert (PreInsertEvent event ) {
@@ -143,10 +136,6 @@ private <T> void validate(
143
136
if ( object == null || persister .getRepresentationStrategy ().getMode () != RepresentationMode .POJO ) {
144
137
return ;
145
138
}
146
- TraversableResolver tr = new HibernateTraversableResolver ( persister , associationsPerEntityPersister , sessionFactory );
147
- Validator validator = factory .usingContext ()
148
- .traversableResolver ( tr )
149
- .getValidator ();
150
139
final Class <?>[] groups = groupsPerOperation .get ( operation );
151
140
if ( groups .length > 0 ) {
152
141
final Set <ConstraintViolation <T >> constraintViolations = validator .validate ( object , groups );
@@ -167,7 +156,7 @@ private <T> void validate(
167
156
builder .append ( toString ( groups ) );
168
157
builder .append ( "\n List of constraint violations:[\n " );
169
158
for ( ConstraintViolation <?> violation : constraintViolations ) {
170
- builder .append ( "\t " ).append ( violation .toString () ).append ("\n " );
159
+ builder .append ( "\t " ).append ( violation .toString () ).append ( "\n " );
171
160
}
172
161
builder .append ( "]" );
173
162
0 commit comments