Skip to content

Commit 4f05b18

Browse files
marko-bekhtasebersole
authored andcommitted
HHH-19210 - Propagate exceptions from building a ValidatorFactory
1 parent 5edc554 commit 4f05b18

File tree

11 files changed

+574
-633
lines changed

11 files changed

+574
-633
lines changed

hibernate-core/src/main/java/org/hibernate/boot/beanvalidation/TypeSafeActivator.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,7 @@
1616
import java.util.Set;
1717
import java.util.StringTokenizer;
1818

19+
import jakarta.validation.NoProviderFoundException;
1920
import jakarta.validation.constraints.Digits;
2021
import jakarta.validation.constraints.Max;
2122
import jakarta.validation.constraints.Min;
@@ -97,14 +98,24 @@ public static void activate(ActivationContext context) {
9798
catch (IntegrationException e) {
9899
final Set<ValidationMode> validationModes = context.getValidationModes();
99100
if ( validationModes.contains( ValidationMode.CALLBACK ) ) {
100-
throw new IntegrationException( "Bean Validation provider was not available, but 'callback' validation was requested", e );
101+
throw new IntegrationException( "Jakarta Validation provider was not available, but 'callback' validation mode was requested", e );
101102
}
102103
else if ( validationModes.contains( ValidationMode.DDL ) ) {
103-
throw new IntegrationException( "Bean Validation provider was not available, but 'ddl' validation was requested", e );
104+
throw new IntegrationException( "Jakarta Validation provider was not available, but 'ddl' validation mode was requested", e );
104105
}
105106
else {
106-
LOG.debug( "Unable to acquire Bean Validation ValidatorFactory, skipping activation" );
107-
return;
107+
if ( e.getCause() != null && e.getCause() instanceof NoProviderFoundException ) {
108+
// all good, we are looking at the ValidationMode.AUTO, and there are no providers available.
109+
// Hence, we just don't enable the Jakarta Validation integration:
110+
LOG.debug( "Unable to acquire Jakarta Validation ValidatorFactory, skipping activation" );
111+
return;
112+
}
113+
else {
114+
// There is a Jakarta Validation provider, but it failed to bootstrap the factory for some reason,
115+
// we should fail and let the user deal with it:
116+
throw e;
117+
118+
}
108119
}
109120
}
110121

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/BeanValidationAutoTest.java

Lines changed: 29 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -4,54 +4,42 @@
44
*/
55
package org.hibernate.orm.test.annotations.beanvalidation;
66

7-
import java.math.BigDecimal;
87
import jakarta.validation.ConstraintViolationException;
8+
import org.hibernate.cfg.ValidationSettings;
9+
import org.hibernate.testing.orm.junit.DomainModel;
10+
import org.hibernate.testing.orm.junit.ServiceRegistry;
11+
import org.hibernate.testing.orm.junit.SessionFactory;
12+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
13+
import org.hibernate.testing.orm.junit.Setting;
14+
import org.junit.jupiter.api.Test;
915

10-
import org.hibernate.boot.beanvalidation.ValidationMode;
11-
import org.junit.Test;
12-
13-
import org.hibernate.Session;
14-
import org.hibernate.Transaction;
15-
import org.hibernate.cfg.Configuration;
16-
17-
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
16+
import java.math.BigDecimal;
1817

19-
import static org.hibernate.cfg.ValidationSettings.JAKARTA_VALIDATION_MODE;
20-
import static org.junit.Assert.assertEquals;
21-
import static org.junit.Assert.fail;
18+
import static org.assertj.core.api.Assertions.assertThat;
19+
import static org.junit.jupiter.api.Assertions.fail;
2220

2321
/**
2422
* @author Emmanuel Bernard
2523
*/
26-
public class BeanValidationAutoTest extends BaseCoreFunctionalTestCase {
24+
@ServiceRegistry(
25+
settings = @Setting(name = ValidationSettings.JAKARTA_VALIDATION_MODE, value = "AUTO")
26+
)
27+
@DomainModel(annotatedClasses = CupHolder.class)
28+
@SessionFactory
29+
class BeanValidationAutoTest {
2730
@Test
28-
public void testListeners() {
29-
CupHolder ch = new CupHolder();
30-
ch.setRadius( new BigDecimal( "12" ) );
31-
Session s = openSession();
32-
Transaction tx = s.beginTransaction();
33-
try {
34-
s.persist( ch );
35-
s.flush();
36-
fail( "invalid object should not be persisted" );
37-
}
38-
catch ( ConstraintViolationException e ) {
39-
assertEquals( 1, e.getConstraintViolations().size() );
40-
}
41-
tx.rollback();
42-
s.close();
43-
}
44-
45-
@Override
46-
protected void configure(Configuration cfg) {
47-
super.configure( cfg );
48-
cfg.setProperty( JAKARTA_VALIDATION_MODE, ValidationMode.AUTO );
49-
}
50-
51-
@Override
52-
protected Class<?>[] getAnnotatedClasses() {
53-
return new Class<?>[] {
54-
CupHolder.class
55-
};
31+
void testListeners(SessionFactoryScope scope) {
32+
scope.inTransaction( s -> {
33+
CupHolder ch = new CupHolder();
34+
ch.setRadius( new BigDecimal( "12" ) );
35+
try {
36+
s.persist( ch );
37+
s.flush();
38+
fail( "invalid object should not be persisted" );
39+
}
40+
catch (ConstraintViolationException e) {
41+
assertThat( e.getConstraintViolations() ).hasSize( 1 );
42+
}
43+
} );
5644
}
5745
}

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/BeanValidationDisabledTest.java

Lines changed: 34 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -4,59 +4,53 @@
44
*/
55
package org.hibernate.orm.test.annotations.beanvalidation;
66

7-
import java.math.BigDecimal;
8-
import java.util.Map;
97
import jakarta.validation.ConstraintViolationException;
10-
11-
import org.hibernate.Session;
12-
import org.hibernate.Transaction;
8+
import org.hibernate.cfg.ValidationSettings;
139
import org.hibernate.mapping.Column;
1410
import org.hibernate.mapping.PersistentClass;
11+
import org.hibernate.testing.orm.junit.DomainModel;
12+
import org.hibernate.testing.orm.junit.ServiceRegistry;
13+
import org.hibernate.testing.orm.junit.SessionFactory;
14+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
15+
import org.hibernate.testing.orm.junit.Setting;
16+
import org.junit.jupiter.api.Test;
1517

16-
import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase;
17-
import org.junit.Test;
18+
import java.math.BigDecimal;
1819

19-
import static org.junit.Assert.assertTrue;
20-
import static org.junit.Assert.fail;
20+
import static org.junit.jupiter.api.Assertions.assertTrue;
21+
import static org.junit.jupiter.api.Assertions.fail;
2122

2223
/**
2324
* @author Emmanuel Bernard
2425
*/
25-
public class BeanValidationDisabledTest extends BaseNonConfigCoreFunctionalTestCase {
26+
@ServiceRegistry(
27+
settings = @Setting(name = ValidationSettings.JAKARTA_VALIDATION_MODE, value = "none")
28+
)
29+
@DomainModel(annotatedClasses = {
30+
Address.class,
31+
CupHolder.class
32+
})
33+
@SessionFactory
34+
class BeanValidationDisabledTest {
2635
@Test
27-
public void testListeners() {
28-
CupHolder ch = new CupHolder();
29-
ch.setRadius( new BigDecimal( "12" ) );
30-
Session s = openSession();
31-
Transaction tx = s.beginTransaction();
32-
try {
33-
s.persist( ch );
34-
s.flush();
35-
}
36-
catch ( ConstraintViolationException e ) {
37-
fail( "invalid object should not be validated" );
38-
}
39-
tx.rollback();
40-
s.close();
36+
void testListeners(SessionFactoryScope scope) {
37+
scope.inTransaction( s -> {
38+
CupHolder ch = new CupHolder();
39+
ch.setRadius( new BigDecimal( "12" ) );
40+
try {
41+
s.persist( ch );
42+
s.flush();
43+
}
44+
catch (ConstraintViolationException e) {
45+
fail( "invalid object should not be validated" );
46+
}
47+
} );
4148
}
4249

4350
@Test
44-
public void testDDLDisabled() {
45-
PersistentClass classMapping = metadata().getEntityBinding( Address.class.getName() );
51+
void testDDLDisabled(SessionFactoryScope scope) {
52+
PersistentClass classMapping = scope.getMetadataImplementor().getEntityBinding( Address.class.getName() );
4653
Column countryColumn = (Column) classMapping.getProperty( "country" ).getSelectables().get( 0 );
47-
assertTrue( "DDL constraints are applied", countryColumn.isNullable() );
48-
}
49-
50-
@Override
51-
protected void addSettings(Map<String,Object> settings) {
52-
settings.put( "jakarta.persistence.validation.mode", "none" );
53-
}
54-
55-
@Override
56-
protected Class<?>[] getAnnotatedClasses() {
57-
return new Class<?>[] {
58-
Address.class,
59-
CupHolder.class
60-
};
54+
assertTrue( countryColumn.isNullable(), "DDL constraints are applied" );
6155
}
6256
}

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/BeanValidationGroupsTest.java

Lines changed: 63 additions & 77 deletions
Original file line numberDiff line numberDiff line change
@@ -4,91 +4,77 @@
44
*/
55
package org.hibernate.orm.test.annotations.beanvalidation;
66

7-
import java.lang.annotation.Annotation;
8-
import java.math.BigDecimal;
97
import jakarta.validation.ConstraintViolationException;
108
import jakarta.validation.constraints.NotNull;
11-
import jakarta.validation.groups.Default;
12-
13-
import org.junit.Test;
14-
15-
import org.hibernate.Session;
169
import org.hibernate.Transaction;
17-
import org.hibernate.cfg.Configuration;
18-
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
10+
import org.hibernate.boot.beanvalidation.BeanValidationIntegrator;
11+
import org.hibernate.cfg.ValidationSettings;
12+
import org.hibernate.testing.orm.junit.DomainModel;
13+
import org.hibernate.testing.orm.junit.ServiceRegistry;
14+
import org.hibernate.testing.orm.junit.SessionFactory;
15+
import org.hibernate.testing.orm.junit.SessionFactoryScope;
16+
import org.hibernate.testing.orm.junit.Setting;
17+
import org.junit.jupiter.api.Test;
18+
19+
import java.lang.annotation.Annotation;
20+
import java.math.BigDecimal;
1921

20-
import static org.junit.Assert.assertEquals;
21-
import static org.junit.Assert.fail;
22+
import static org.assertj.core.api.Assertions.assertThat;
23+
import static org.junit.jupiter.api.Assertions.fail;
2224

2325
/**
2426
* @author Emmanuel Bernard
2527
*/
26-
public class BeanValidationGroupsTest extends BaseCoreFunctionalTestCase {
27-
@Test
28-
public void testListeners() {
29-
CupHolder ch = new CupHolder();
30-
ch.setRadius( new BigDecimal( "12" ) );
31-
Session s = openSession();
32-
Transaction tx = s.beginTransaction();
33-
try {
34-
s.persist( ch );
35-
s.flush();
36-
}
37-
catch ( ConstraintViolationException e ) {
38-
fail( "invalid object should not be validated" );
39-
}
40-
try {
41-
ch.setRadius( null );
42-
s.flush();
43-
}
44-
catch ( ConstraintViolationException e ) {
45-
fail( "invalid object should not be validated" );
46-
}
47-
try {
48-
s.remove( ch );
49-
s.flush();
50-
fail( "invalid object should not be persisted" );
51-
}
52-
catch ( ConstraintViolationException e ) {
53-
assertEquals( 1, e.getConstraintViolations().size() );
54-
// TODO - seems this explicit case is necessary with JDK 5 (at least on Mac). With Java 6 there is no problem
55-
Annotation annotation = e.getConstraintViolations()
56-
.iterator()
57-
.next()
58-
.getConstraintDescriptor()
59-
.getAnnotation();
60-
assertEquals(
61-
NotNull.class,
62-
annotation.annotationType()
63-
);
64-
}
65-
tx.rollback();
66-
s.close();
67-
}
28+
@ServiceRegistry(settings = {
29+
@Setting(name = ValidationSettings.JAKARTA_PERSIST_VALIDATION_GROUP, value = ""),
30+
@Setting(name = ValidationSettings.JAKARTA_UPDATE_VALIDATION_GROUP, value = ""),
31+
@Setting(name = ValidationSettings.JAKARTA_REMOVE_VALIDATION_GROUP,
32+
value = "jakarta.validation.groups.Default, org.hibernate.orm.test.annotations.beanvalidation.Strict"),
33+
@Setting(name = BeanValidationIntegrator.APPLY_CONSTRAINTS, value = "false"),
34+
@Setting(name = ValidationSettings.JAKARTA_VALIDATION_MODE, value = "auto"),
35+
})
36+
@DomainModel(annotatedClasses = {
37+
CupHolder.class
38+
})
39+
@SessionFactory
40+
class BeanValidationGroupsTest {
6841

69-
@Override
70-
protected void configure(Configuration cfg) {
71-
super.configure( cfg );
72-
cfg.setProperty(
73-
"javax.persistence.validation.group.pre-persist",
74-
""
75-
);
76-
cfg.setProperty(
77-
"javax.persistence.validation.group.pre-update",
78-
""
79-
);
80-
cfg.setProperty(
81-
"javax.persistence.validation.group.pre-remove",
82-
Default.class.getName() + ", " + Strict.class.getName()
83-
);
84-
cfg.setProperty( "hibernate.validator.apply_to_ddl", "false" );
85-
cfg.setProperty( "jakarta.persistence.validation.mode", "auto" );
86-
}
87-
88-
@Override
89-
protected Class<?>[] getAnnotatedClasses() {
90-
return new Class<?>[] {
91-
CupHolder.class
92-
};
42+
@Test
43+
void testListeners(SessionFactoryScope scope) {
44+
scope.inSession( s -> {
45+
CupHolder ch = new CupHolder();
46+
ch.setRadius( new BigDecimal( "12" ) );
47+
Transaction tx = s.beginTransaction();
48+
try {
49+
s.persist( ch );
50+
s.flush();
51+
}
52+
catch (ConstraintViolationException e) {
53+
fail( "invalid object should not be validated" );
54+
}
55+
try {
56+
ch.setRadius( null );
57+
s.flush();
58+
}
59+
catch (ConstraintViolationException e) {
60+
fail( "invalid object should not be validated" );
61+
}
62+
try {
63+
s.remove( ch );
64+
s.flush();
65+
fail( "invalid object should not be persisted" );
66+
}
67+
catch (ConstraintViolationException e) {
68+
assertThat( e.getConstraintViolations() ).hasSize( 1 );
69+
// TODO - seems this explicit case is necessary with JDK 5 (at least on Mac). With Java 6 there is no problem
70+
Annotation annotation = e.getConstraintViolations()
71+
.iterator()
72+
.next()
73+
.getConstraintDescriptor()
74+
.getAnnotation();
75+
assertThat( annotation.annotationType() ).isEqualTo( NotNull.class );
76+
}
77+
tx.rollback();
78+
} );
9379
}
9480
}

0 commit comments

Comments
 (0)