From af1172c31ce19c9681e158d2e1b44556cc1c1c47 Mon Sep 17 00:00:00 2001 From: Vlad Mihalcea Date: Thu, 13 Dec 2018 16:46:12 +0200 Subject: [PATCH] HHH-13163 - Fix DDLWithoutCallbackTest#testRangeChecksGetApplied which fails on MariaDB --- .../annotations/beanvalidation/Address.java | 109 +++++++++++++ .../annotations/beanvalidation/CupHolder.java | 43 +++++ .../DDLWithoutCallbackTest.java | 150 ++++++++++++++++++ .../annotations/beanvalidation/MinMax.java} | 15 +- .../annotations/beanvalidation/Strict.java | 15 ++ .../DDLWithoutCallbackTest.java | 124 --------------- .../SessionFactoryBasedFunctionalTest.java | 36 +++++ 7 files changed, 362 insertions(+), 130 deletions(-) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Address.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/CupHolder.java create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/DDLWithoutCallbackTest.java rename hibernate-core/src/{test2/java/org/hibernate/test/annotations/beanvalidation/Range.java => test/java/org/hibernate/orm/test/annotations/beanvalidation/MinMax.java} (70%) create mode 100644 hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Strict.java delete mode 100644 hibernate-core/src/test2/java/org/hibernate/test/annotations/beanvalidation/DDLWithoutCallbackTest.java diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Address.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Address.java new file mode 100644 index 000000000000..7b1b8d142db0 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Address.java @@ -0,0 +1,109 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ + +package org.hibernate.orm.test.annotations.beanvalidation; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.Transient; +import javax.validation.constraints.AssertTrue; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; +import javax.validation.constraints.NotNull; +import javax.validation.constraints.Pattern; +import javax.validation.constraints.Size; + +@Entity +public class Address { + @NotNull + public static String blacklistedZipCode; + + private String line1; + private String line2; + private String zip; + private String state; + @Size(max = 20) + @NotNull + private String country; + private long id; + private boolean internalValid = true; + @Min(-2) + @Max(value = 50) + public int floor; + + public String getCountry() { + return country; + } + + public void setCountry(String country) { + this.country = country; + } + + @NotNull + public String getLine1() { + return line1; + } + + public void setLine1(String line1) { + this.line1 = line1; + } + + public String getLine2() { + return line2; + } + + public void setLine2(String line2) { + this.line2 = line2; + } + + @Size(max = 3) + @NotNull + public String getState() { + return state; + } + + public void setState(String state) { + this.state = state; + } + + @Size(max = 5) + @Pattern(regexp = "[0-9]+") + @NotNull + public String getZip() { + return zip; + } + + public void setZip(String zip) { + this.zip = zip; + } + + @AssertTrue + @Transient + public boolean isValid() { + return true; + } + + @AssertTrue + @Transient + private boolean isInternalValid() { + return internalValid; + } + + public void setInternalValid(boolean internalValid) { + this.internalValid = internalValid; + } + + @Id + @Min(1) + @Max(2000) + public long getId() { + return id; + } + + public void setId(long id) { + this.id = id; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/CupHolder.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/CupHolder.java new file mode 100644 index 000000000000..04af03118cfd --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/CupHolder.java @@ -0,0 +1,43 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ + +package org.hibernate.orm.test.annotations.beanvalidation; +import java.math.BigDecimal; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.validation.constraints.Max; +import javax.validation.constraints.NotNull; + +/** + * @author Emmanuel Bernard + */ +@Entity +public class CupHolder { + @Id + @GeneratedValue + private Integer id; + private BigDecimal radius; + + public Integer getId() { + return id; + } + + public void setId(Integer id) { + this.id = id; + } + + @Max(value = 10, message = "Radius way out") + @NotNull(groups = Strict.class) + public BigDecimal getRadius() { + return radius; + } + + public void setRadius(BigDecimal radius) { + this.radius = radius; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/DDLWithoutCallbackTest.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/DDLWithoutCallbackTest.java new file mode 100644 index 000000000000..2705f999449c --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/DDLWithoutCallbackTest.java @@ -0,0 +1,150 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ +package org.hibernate.orm.test.annotations.beanvalidation; + +import java.math.BigDecimal; +import javax.persistence.Entity; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.PersistenceException; +import javax.validation.ConstraintViolationException; + +import org.hibernate.boot.MetadataSources; +import org.hibernate.boot.registry.StandardServiceRegistryBuilder; +import org.hibernate.dialect.Dialect; +import org.hibernate.mapping.Column; +import org.hibernate.mapping.PersistentClass; + +import org.hibernate.testing.DialectChecks; +import org.hibernate.testing.RequiresDialectFeature; +import org.hibernate.testing.junit5.SessionFactoryBasedFunctionalTest; +import org.junit.jupiter.api.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.fail; + +/** + * @author Vladimir Klyushnikov + * @author Hardy Ferentschik + */ +public class DDLWithoutCallbackTest extends SessionFactoryBasedFunctionalTest { + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + Address.class, + CupHolder.class, + MinMax.class, + RangeEntity.class + }; + } + + @Override + protected void applySettings(StandardServiceRegistryBuilder builder) { + builder.applySetting( "javax.persistence.validation.mode", "ddl" ); + } + + protected boolean exportSchema() { + return true; + } + + @Override + protected boolean isCleanupTestDataRequired() { + return true; + } + + @Test + @RequiresDialectFeature(DialectChecks.SupportsColumnCheck.class) + public void testListeners() { + CupHolder ch = new CupHolder(); + ch.setRadius( new BigDecimal( "12" ) ); + assertDatabaseConstraintViolationThrown( ch ); + } + + @Test + @RequiresDialectFeature(DialectChecks.SupportsColumnCheck.class) + public void testMinAndMaxChecksGetApplied() { + MinMax minMax = new MinMax( 1 ); + assertDatabaseConstraintViolationThrown( minMax ); + + minMax = new MinMax( 11 ); + assertDatabaseConstraintViolationThrown( minMax ); + + final MinMax validMinMax = new MinMax( 5 ); + + doInHibernate( this::sessionFactory, session -> { + session.persist( validMinMax ); + } ); + } + + @Test + @RequiresDialectFeature(DialectChecks.SupportsColumnCheck.class) + public void testRangeChecksGetApplied() { + RangeEntity range = new RangeEntity( 1 ); + assertDatabaseConstraintViolationThrown( range ); + + range = new RangeEntity( 11 ); + assertDatabaseConstraintViolationThrown( range ); + + RangeEntity validRange = new RangeEntity( 5 ); + + doInHibernate( this::sessionFactory, session -> { + session.persist( validRange ); + } ); + } + + @Test + public void testDDLEnabled() { + PersistentClass classMapping = getMetadata().getEntityBinding( Address.class.getName() ); + Column countryColumn = (Column) classMapping.getProperty( "country" ).getMappedColumns().get( 0 ); + assertFalse( "DDL constraints are not applied", countryColumn.isNullable() ); + } + + private void assertDatabaseConstraintViolationThrown(Object o) { + doInHibernate( this::sessionFactory, session -> { + try { + session.persist( o ); + session.flush(); + fail( "expecting SQL constraint violation" ); + } + catch (PersistenceException pe) { + final Throwable cause = pe.getCause(); + if ( cause instanceof ConstraintViolationException ) { + fail( "invalid object should not be validated" ); + } + else if ( cause instanceof org.hibernate.exception.ConstraintViolationException ) { + if ( Dialect.getDialect().supportsColumnCheck() ) { + // expected + } + else { + org.hibernate.exception.ConstraintViolationException cve = (org.hibernate.exception.ConstraintViolationException) cause; + fail( "Unexpected SQL constraint violation [" + cve.getConstraintName() + "] : " + cve.getSQLException() ); + } + } + } + } ); + } + + @Entity(name = "RangeEntity") + public static class RangeEntity { + + @Id + @GeneratedValue + private Long id; + + @org.hibernate.validator.constraints.Range(min = 2, max = 10) + private Integer rangeProperty; + + private RangeEntity() { + } + + public RangeEntity(Integer value) { + this.rangeProperty = value; + } + } +} diff --git a/hibernate-core/src/test2/java/org/hibernate/test/annotations/beanvalidation/Range.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/MinMax.java similarity index 70% rename from hibernate-core/src/test2/java/org/hibernate/test/annotations/beanvalidation/Range.java rename to hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/MinMax.java index 5350feb61e15..3daecb0d5f80 100644 --- a/hibernate-core/src/test2/java/org/hibernate/test/annotations/beanvalidation/Range.java +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/MinMax.java @@ -5,30 +5,33 @@ * See the lgpl.txt file in the root directory or . */ -package org.hibernate.test.annotations.beanvalidation; -import javax.persistence.Column; +package org.hibernate.orm.test.annotations.beanvalidation; import javax.persistence.Entity; import javax.persistence.GeneratedValue; import javax.persistence.Id; +import javax.persistence.Column; +import javax.validation.constraints.Max; +import javax.validation.constraints.Min; /** * @author Hardy Ferentschik */ @Entity -public class Range { +public class MinMax { @Id @GeneratedValue private Long id; - @org.hibernate.validator.constraints.Range(min = 2, max = 10) + @Max(10) + @Min(2) @Column(name = "`value`") private Integer value; - private Range() { + private MinMax() { } - public Range(Integer value) { + public MinMax(Integer value) { this.value = value; } } diff --git a/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Strict.java b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Strict.java new file mode 100644 index 000000000000..7efce0414354 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/orm/test/annotations/beanvalidation/Strict.java @@ -0,0 +1,15 @@ +/* + * Hibernate, Relational Persistence for Idiomatic Java + * + * License: GNU Lesser General Public License (LGPL), version 2.1 or later. + * See the lgpl.txt file in the root directory or . + */ + +package org.hibernate.orm.test.annotations.beanvalidation; + + +/** + * @author Emmanuel Bernard + */ +public interface Strict { +} diff --git a/hibernate-core/src/test2/java/org/hibernate/test/annotations/beanvalidation/DDLWithoutCallbackTest.java b/hibernate-core/src/test2/java/org/hibernate/test/annotations/beanvalidation/DDLWithoutCallbackTest.java deleted file mode 100644 index 15597c45f018..000000000000 --- a/hibernate-core/src/test2/java/org/hibernate/test/annotations/beanvalidation/DDLWithoutCallbackTest.java +++ /dev/null @@ -1,124 +0,0 @@ -/* - * Hibernate, Relational Persistence for Idiomatic Java - * - * License: GNU Lesser General Public License (LGPL), version 2.1 or later. - * See the lgpl.txt file in the root directory or . - */ -package org.hibernate.test.annotations.beanvalidation; - -import java.math.BigDecimal; -import java.util.Map; -import javax.persistence.PersistenceException; -import javax.validation.ConstraintViolationException; - -import org.hibernate.Session; -import org.hibernate.Transaction; -import org.hibernate.mapping.Column; -import org.hibernate.mapping.PersistentClass; - -import org.hibernate.testing.DialectChecks; -import org.hibernate.testing.RequiresDialectFeature; -import org.hibernate.testing.junit4.BaseNonConfigCoreFunctionalTestCase; -import org.junit.Test; - -import static org.junit.Assert.assertFalse; -import static org.junit.Assert.fail; - -/** - * @author Vladimir Klyushnikov - * @author Hardy Ferentschik - */ -public class DDLWithoutCallbackTest extends BaseNonConfigCoreFunctionalTestCase { - @Test - @RequiresDialectFeature(DialectChecks.SupportsColumnCheck.class) - public void testListeners() { - CupHolder ch = new CupHolder(); - ch.setRadius( new BigDecimal( "12" ) ); - assertDatabaseConstraintViolationThrown( ch ); - } - - @Test - @RequiresDialectFeature(DialectChecks.SupportsColumnCheck.class) - public void testMinAndMaxChecksGetApplied() { - MinMax minMax = new MinMax( 1 ); - assertDatabaseConstraintViolationThrown( minMax ); - - minMax = new MinMax( 11 ); - assertDatabaseConstraintViolationThrown( minMax ); - - minMax = new MinMax( 5 ); - Session s = openSession(); - Transaction tx = s.beginTransaction(); - s.persist( minMax ); - s.flush(); - tx.rollback(); - s.close(); - } - - @Test - @RequiresDialectFeature(DialectChecks.SupportsColumnCheck.class) - public void testRangeChecksGetApplied() { - Range range = new Range( 1 ); - assertDatabaseConstraintViolationThrown( range ); - - range = new Range( 11 ); - assertDatabaseConstraintViolationThrown( range ); - - range = new Range( 5 ); - Session s = openSession(); - Transaction tx = s.beginTransaction(); - s.persist( range ); - s.flush(); - tx.rollback(); - s.close(); - } - - @Test - public void testDDLEnabled() { - PersistentClass classMapping = metadata().getEntityBinding( Address.class.getName() ); - Column countryColumn = (Column) classMapping.getProperty( "country" ).getColumnIterator().next(); - assertFalse( "DDL constraints are not applied", countryColumn.isNullable() ); - } - - @Override - protected void addSettings(Map settings) { - settings.put( "javax.persistence.validation.mode", "ddl" ); - } - - @Override - protected Class[] getAnnotatedClasses() { - return new Class[] { - Address.class, - CupHolder.class, - MinMax.class, - Range.class - }; - } - - private void assertDatabaseConstraintViolationThrown(Object o) { - Session s = openSession(); - Transaction tx = s.beginTransaction(); - try { - s.persist( o ); - s.flush(); - fail( "expecting SQL constraint violation" ); - } - catch (PersistenceException pe) { - final Throwable cause = pe.getCause(); - if ( cause instanceof ConstraintViolationException ) { - fail( "invalid object should not be validated" ); - } - else if ( cause instanceof org.hibernate.exception.ConstraintViolationException ) { - if ( getDialect().supportsColumnCheck() ) { - // expected - } - else { - org.hibernate.exception.ConstraintViolationException cve = (org.hibernate.exception.ConstraintViolationException) cause; - fail( "Unexpected SQL constraint violation [" + cve.getConstraintName() + "] : " + cve.getSQLException() ); - } - } - } - tx.rollback(); - s.close(); - } -} diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java index 20538970192a..abfd4916f454 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit5/SessionFactoryBasedFunctionalTest.java @@ -6,7 +6,11 @@ */ package org.hibernate.testing.junit5; +import java.util.Arrays; import java.util.EnumSet; +import javax.persistence.criteria.CriteriaBuilder; +import javax.persistence.criteria.CriteriaDelete; +import javax.persistence.criteria.Root; import org.hibernate.boot.Metadata; import org.hibernate.boot.MetadataSources; @@ -23,8 +27,12 @@ import org.hibernate.tool.schema.internal.Helper; import org.hibernate.tool.schema.spi.SchemaManagementToolCoordinator; +import org.junit.jupiter.api.AfterEach; + import org.jboss.logging.Logger; +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; + /** * @author Steve Ebersole */ @@ -108,6 +116,15 @@ protected boolean exportSchema() { } protected void applyMetadataSources(MetadataSources metadataSources) { + for ( Class annotatedClass : getAnnotatedClasses() ) { + metadataSources.addAnnotatedClass( annotatedClass ); + } + } + + protected static final Class[] NO_CLASSES = new Class[0]; + + protected Class[] getAnnotatedClasses() { + return NO_CLASSES; } @Override @@ -123,4 +140,23 @@ public SessionFactoryProducer getSessionFactoryProducer() { protected Metadata getMetadata(){ return metadata; } + + @AfterEach + public final void afterTest() { + if ( isCleanupTestDataRequired() ) { + cleanupTestData(); + } + } + + protected boolean isCleanupTestDataRequired() { + return false; + } + + protected void cleanupTestData() { + doInHibernate(this::sessionFactory, session -> { + Arrays.stream( getAnnotatedClasses() ).forEach( annotatedClass -> + session.createQuery( "delete from " + annotatedClass.getSimpleName() ).executeUpdate() + ); + }); + } }