From faae3745eee6463ec28462982acb80de45843cbb Mon Sep 17 00:00:00 2001 From: Mykhaylo Gnylorybov Date: Fri, 19 Jan 2018 18:03:57 +0200 Subject: [PATCH] HHH-12227 {h-schema} is not replaced in @Formula --- .../entity/AbstractEntityPersister.java | 2 + ...AbstractSchemaSubstitutionFormulaTest.java | 140 ++++++++++++++++++ ...laTemplateEmptySchemaSubstitutionTest.java | 27 ++++ ...FormulaTemplateSchemaSubstitutionTest.java | 45 ++++++ 4 files changed, 214 insertions(+) create mode 100644 hibernate-core/src/test/java/org/hibernate/persister/entity/AbstractSchemaSubstitutionFormulaTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java create mode 100644 hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java diff --git a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java index f807d53b40..5dcb869128 100644 --- a/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java +++ b/hibernate-core/src/main/java/org/hibernate/persister/entity/AbstractEntityPersister.java @@ -94,6 +94,7 @@ import org.hibernate.loader.entity.EntityLoader; import org.hibernate.loader.entity.UniqueEntityLoader; import org.hibernate.mapping.Column; import org.hibernate.mapping.Component; +import org.hibernate.mapping.Formula; import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.Property; import org.hibernate.mapping.Selectable; @@ -647,6 +648,7 @@ public abstract class AbstractEntityPersister colAliases[k] = thing.getAlias( dialect, prop.getValue().getTable() ); if ( thing.isFormula() ) { foundFormula = true; + ( (Formula) thing ).setFormula( substituteBrackets( ( (Formula) thing ).getFormula() ) ); formulaTemplates[k] = thing.getTemplate( dialect, factory.getSqlFunctionRegistry() ); } else { diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/AbstractSchemaSubstitutionFormulaTest.java b/hibernate-core/src/test/java/org/hibernate/persister/entity/AbstractSchemaSubstitutionFormulaTest.java new file mode 100644 index 0000000000..6ffb4cf4b8 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/persister/entity/AbstractSchemaSubstitutionFormulaTest.java @@ -0,0 +1,140 @@ +/* + * 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.persister.entity; + +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.ManyToOne; +import javax.persistence.Table; + +import org.hibernate.annotations.Formula; +import org.hibernate.dialect.H2Dialect; + +import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Mykhaylo Gnylorybov + */ +public abstract class AbstractSchemaSubstitutionFormulaTest extends BaseCoreFunctionalTestCase { + + protected static final String SCHEMA_PLACEHOLDER = "h-schema"; + + @Test + public void test() { + final String className = FooBar.class.getName(); + final AbstractEntityPersister persister = (AbstractEntityPersister) sessionFactory() + .getMetamodel().entityPersister( className ); + final String formula = persister.getSubclassFormulaTemplateClosure()[0]; + + doInHibernate( this::sessionFactory, session -> { + Foo foo = new Foo(); + foo.id = 1; + foo.name = "fooName"; + session.persist( foo ); + + Bar bar = new Bar(); + bar.id = 2; + bar.name = "barName"; + session.persist( bar ); + + FooBar fooBar = new FooBar(); + fooBar.id = 3; + fooBar.bar = bar; + fooBar.foo = foo; + + session.persist( fooBar ); + } ); + + doInHibernate( this::sessionFactory, session -> { + FooBar entity = session.find( FooBar.class, 3 ); + assertTrue( "Invalid result of formula expression: ", entity.isValid ); + } ); + + + } + + abstract void validate(String formula); + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { + FooBar.class, + Bar.class, + Foo.class + }; + } + + @Entity(name = "FOOBAR") + @Table(name = "FOOBAR") + public static class FooBar { + + @Id + @Column(name = "ID") + public Integer id; + + @ManyToOne + @JoinColumn(name = "FOO_ID") + public Foo foo; + + @ManyToOne + @JoinColumn(name = "BAR_ID") + public Bar bar; + + @Formula("CASE WHEN (\n" + + " EXISTS (\n" + + " SELECT *\n" + + " FROM {h-schema}Foo foo\n" + + " JOIN {h-schema}FooBar fooBar\n" + + " ON foo.ID = fooBar.FOO_ID" + + " WHERE foo.name IS NOT NULL\n" + + " )\n" + + " AND\n" + + " EXISTS (\n" + + " SELECT *\n" + + " FROM {h-schema}Bar bar\n" + + " JOIN {h-schema}FooBar fooBar\n" + + " ON bar.ID = fooBar.BAR_ID\n" + + " WHERE bar.name IS NOT NULL\n" + + " ))\n" + + " THEN 1\n" + + " ELSE 0\n" + + "END") + public Boolean isValid; + } + + @Entity(name = "FOO") + @Table(name = "FOO") + public static class Foo { + + @Id + @Column(name = "ID") + public Integer id; + + @Column(name = "name") + public String name; + } + + @Entity(name = "BAR") + @Table(name = "BAR") + public static class Bar { + + @Id + @Column(name = "ID") + public Integer id; + + @Column(name = "name") + public String name; + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java b/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java new file mode 100644 index 0000000000..843d9bcf49 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateEmptySchemaSubstitutionTest.java @@ -0,0 +1,27 @@ +/* + * 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.persister.entity; + +import org.hibernate.dialect.H2Dialect; + +import org.hibernate.testing.RequiresDialect; + +import static org.junit.Assert.assertFalse; +import static org.junit.Assert.assertTrue; + +/** + * @author Mykhaylo Gnylorybov + */ +@RequiresDialect(H2Dialect.class) +public class FormulaTemplateEmptySchemaSubstitutionTest extends AbstractSchemaSubstitutionFormulaTest { + + @Override + void validate(String formula) { + assertTrue( "Formula should not contain {} characters", formula.matches( "^[^{}]+$" ) ); + assertFalse( "Formula should not contain hibernate placeholder", formula.contains( SCHEMA_PLACEHOLDER ) ); + } +} diff --git a/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java b/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java new file mode 100644 index 0000000000..967f0de7f5 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/persister/entity/FormulaTemplateSchemaSubstitutionTest.java @@ -0,0 +1,45 @@ +/* + * 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.persister.entity; + +import java.util.Properties; + +import org.hibernate.cfg.Configuration; +import org.hibernate.dialect.H2Dialect; + +import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; +import org.junit.Test; + +import static org.hibernate.testing.transaction.TransactionUtil.doInHibernate; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertTrue; + +@RequiresDialect(H2Dialect.class) +public class FormulaTemplateSchemaSubstitutionTest extends AbstractSchemaSubstitutionFormulaTest { + + private static final String CUSTOM_SCHEMA = "CUSTOM_SCHEMA"; + + @Override + protected void configure(Configuration configuration) { + final Properties properties = new Properties(); + properties.put( "hibernate.default_schema", CUSTOM_SCHEMA ); + configuration.addProperties( properties ); + } + + @Override + protected String createSecondSchema() { + return CUSTOM_SCHEMA; + } + + @Override + void validate(String formula) { + assertEquals( "Formula should not contain {} characters", + 4, formula.split( CUSTOM_SCHEMA + ".", -1 ).length - 1 + ); + } +}