diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java b/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java index 46eb4a16e2..8676f63d12 100644 --- a/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java +++ b/hibernate-core/src/main/java/org/hibernate/cfg/AbstractPropertyHolder.java @@ -285,7 +285,7 @@ public abstract class AbstractPropertyHolder implements PropertyHolder { Map currentJoinTableOverride = buildJoinTableOverride( current, getPath() ); currentOverride.putAll( columnOverride ); //subclasses have precedence over superclasses currentJoinOverride.putAll( joinColumnOverride ); //subclasses have precedence over superclasses - currentJoinOverride.putAll( joinColumnOverride ); //subclasses have precedence over superclasses + currentJoinTableOverride.putAll( joinTableOverride ); //subclasses have precedence over superclasses columnOverride = currentOverride; joinColumnOverride = currentJoinOverride; joinTableOverride = currentJoinTableOverride; diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/id/sequences/HibernateSequenceTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/id/sequences/HibernateSequenceTest.java index 85f2f685e7..624ee0f201 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/annotations/id/sequences/HibernateSequenceTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/id/sequences/HibernateSequenceTest.java @@ -36,9 +36,11 @@ public class HibernateSequenceTest extends BaseCoreFunctionalTestCase { protected void configure(Configuration cfg) { super.configure( cfg ); cfg.addResource( "org/hibernate/test/annotations/id/sequences/orm.xml" ); - cfg.setProperty( - Environment.URL, cfg.getProperty( Environment.URL ) + ";INIT=CREATE SCHEMA IF NOT EXISTS " + SCHEMA_NAME - ); + } + + @Override + protected String createSecondSchema() { + return SCHEMA_NAME; } @Test diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/override/AssociationOverrideSchemaTest.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/override/AssociationOverrideSchemaTest.java new file mode 100644 index 0000000000..059d1cdbc6 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/override/AssociationOverrideSchemaTest.java @@ -0,0 +1,58 @@ +package org.hibernate.test.annotations.override; + +import java.util.Iterator; + +import org.junit.Assert; +import org.junit.Test; + +import org.hibernate.dialect.H2Dialect; +import org.hibernate.mapping.Table; +import org.hibernate.test.util.SchemaUtil; +import org.hibernate.testing.RequiresDialect; +import org.hibernate.testing.TestForIssue; +import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +@RequiresDialect({ H2Dialect.class }) +@TestForIssue(jiraKey = "HHH-6662") +public class AssociationOverrideSchemaTest extends BaseCoreFunctionalTestCase { + public static final String SCHEMA_NAME = "OTHER_SCHEMA"; + public static final String TABLE_NAME = "BLOG_TAGS"; + public static final String ID_COLUMN_NAME = "BLOG_ID"; + public static final String VALUE_COLUMN_NAME = "BLOG_TAG"; + + @Override + protected Class[] getAnnotatedClasses() { + return new Class[] { Entry.class, BlogEntry.class }; + } + + @Override + protected String createSecondSchema() { + return SCHEMA_NAME; + } + + @Test + public void testJoinTableSchemaName() { + Iterator tableIterator = configuration().getTableMappings(); + while ( tableIterator.hasNext() ) { + Table table = tableIterator.next(); + if ( TABLE_NAME.equals( table.getName() ) ) { + Assert.assertEquals( SCHEMA_NAME, table.getSchema() ); + return; + } + } + Assert.fail(); + } + + @Test + public void testJoinTableJoinColumnName() { + Assert.assertTrue( SchemaUtil.isColumnPresent( TABLE_NAME, ID_COLUMN_NAME, configuration() ) ); + } + + @Test + public void testJoinTableColumnName() { + Assert.assertTrue( SchemaUtil.isColumnPresent( TABLE_NAME, VALUE_COLUMN_NAME, configuration() ) ); + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/override/BlogEntry.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/override/BlogEntry.java new file mode 100644 index 0000000000..26f5613c65 --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/override/BlogEntry.java @@ -0,0 +1,56 @@ +package org.hibernate.test.annotations.override; + +import javax.persistence.AssociationOverride; +import javax.persistence.AttributeOverride; +import javax.persistence.Column; +import javax.persistence.Entity; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.Table; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +@Entity +@Table(schema = AssociationOverrideSchemaTest.SCHEMA_NAME) +@AssociationOverride(name = "tags", + joinTable = @JoinTable(name = AssociationOverrideSchemaTest.TABLE_NAME, + joinColumns = @JoinColumn(name = AssociationOverrideSchemaTest.ID_COLUMN_NAME), + schema = AssociationOverrideSchemaTest.SCHEMA_NAME)) +@AttributeOverride(name = "tags", column = @Column(name = AssociationOverrideSchemaTest.VALUE_COLUMN_NAME)) +public class BlogEntry extends Entry { + private String text; + + @Override + public boolean equals(Object o) { + if ( this == o ) return true; + if ( !( o instanceof BlogEntry ) ) return false; + if ( !super.equals( o ) ) return false; + + BlogEntry blogEntry = (BlogEntry) o; + + if ( text != null ? !text.equals( blogEntry.text ) : blogEntry.text != null ) return false; + + return true; + } + + @Override + public int hashCode() { + int result = super.hashCode(); + result = 31 * result + ( text != null ? text.hashCode() : 0 ); + return result; + } + + @Override + public String toString() { + return "BlogEntry(" + super.toString() + ", text = " + text + ")"; + } + + public String getText() { + return text; + } + + public void setText(String text) { + this.text = text; + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/annotations/override/Entry.java b/hibernate-core/src/test/java/org/hibernate/test/annotations/override/Entry.java new file mode 100644 index 0000000000..36a5570e1f --- /dev/null +++ b/hibernate-core/src/test/java/org/hibernate/test/annotations/override/Entry.java @@ -0,0 +1,73 @@ +package org.hibernate.test.annotations.override; + +import java.io.Serializable; +import java.util.HashSet; +import java.util.Set; +import javax.persistence.Column; +import javax.persistence.ElementCollection; +import javax.persistence.FetchType; +import javax.persistence.GeneratedValue; +import javax.persistence.Id; +import javax.persistence.JoinColumn; +import javax.persistence.JoinTable; +import javax.persistence.MappedSuperclass; + +import org.hibernate.annotations.Fetch; +import org.hibernate.annotations.FetchMode; + +/** + * @author Lukasz Antoniak (lukasz dot antoniak at gmail dot com) + */ +@MappedSuperclass +public abstract class Entry implements Serializable { + @Id + @GeneratedValue + private Long id; + + @ElementCollection(fetch = FetchType.EAGER) + @JoinTable(name = "TAGS", joinColumns = @JoinColumn(name = "ID")) + @Column(name = "KEYWORD") + @Fetch(FetchMode.JOIN) + private Set tags = new HashSet(); + + @Override + public boolean equals(Object o) { + if ( this == o ) return true; + if ( !( o instanceof Entry ) ) return false; + + Entry entry = (Entry) o; + + if ( id != null ? !id.equals( entry.id ) : entry.id != null ) return false; + if ( tags != null ? !tags.equals( entry.tags ) : entry.tags != null ) return false; + + return true; + } + + @Override + public int hashCode() { + int result = id != null ? id.hashCode() : 0; + result = 31 * result + ( tags != null ? tags.hashCode() : 0 ); + return result; + } + + @Override + public String toString() { + return "Entry(id = " + id + ", tags = " + tags + ")"; + } + + public Long getId() { + return id; + } + + public void setId(Long id) { + this.id = id; + } + + public Set getTags() { + return tags; + } + + public void setTags(Set tags) { + this.tags = tags; + } +} \ No newline at end of file diff --git a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/oracle/OracleCustomSQLTest.java b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/oracle/OracleCustomSQLTest.java index b40b369cb3..d8c634de49 100644 --- a/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/oracle/OracleCustomSQLTest.java +++ b/hibernate-core/src/test/java/org/hibernate/test/sql/hand/custom/oracle/OracleCustomSQLTest.java @@ -23,6 +23,8 @@ */ package org.hibernate.test.sql.hand.custom.oracle; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; import org.hibernate.dialect.Oracle9iDialect; import org.hibernate.test.sql.hand.custom.CustomStoredProcTestSupport; import org.hibernate.testing.RequiresDialect; diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java index eac760f04f..d407c2b253 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/BaseEnversJPAFunctionalTestCase.java @@ -36,6 +36,7 @@ import org.jboss.logging.Logger; import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.H2Dialect; import org.hibernate.ejb.AvailableSettings; import org.hibernate.ejb.Ejb3Configuration; import org.hibernate.ejb.EntityManagerFactoryImpl; @@ -54,6 +55,7 @@ import org.junit.After; import org.hibernate.testing.AfterClassOnce; import org.hibernate.testing.BeforeClassOnce; import org.hibernate.testing.jta.TestingJtaPlatformImpl; +import org.hibernate.testing.junit4.Helper; /** * @author Strong Liu (stliu@hibernate.org) @@ -93,6 +95,7 @@ public abstract class BaseEnversJPAFunctionalTestCase extends AbstractEnversTest log.trace( "Building session factory" ); ejb3Configuration = buildConfiguration(); ejb3Configuration.configure( getConfig() ); + preConfigure( ejb3Configuration ); configure(ejb3Configuration); afterConfigurationBuilt( ejb3Configuration ); @@ -106,6 +109,19 @@ public abstract class BaseEnversJPAFunctionalTestCase extends AbstractEnversTest afterEntityManagerFactoryBuilt(); } + + private void preConfigure(Ejb3Configuration ejb3Configuration) { + if ( createSchema() ) { + final String secondSchemaName = createSecondSchema(); + if ( StringHelper.isNotEmpty( secondSchemaName ) ) { + if ( !( getDialect() instanceof H2Dialect ) ) { + throw new UnsupportedOperationException( "Only H2 dialect supports creation of second schema." ); + } + Helper.createH2Schema( secondSchemaName, ejb3Configuration.getHibernateConfiguration() ); + } + } + } + public void configure(Ejb3Configuration cfg) { } @@ -219,6 +235,15 @@ public abstract class BaseEnversJPAFunctionalTestCase extends AbstractEnversTest protected boolean createSchema() { return true; } + + /** + * Feature supported only by H2 dialect. + * @return Provide not empty name to create second schema. + */ + protected String createSecondSchema() { + return null; + } + protected boolean isAudit() { return true; } diff --git a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java index 11aa42ea3f..836cd7ad7d 100644 --- a/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java +++ b/hibernate-envers/src/test/java/org/hibernate/envers/test/integration/reventity/DifferentDBSchemaTest.java @@ -30,10 +30,14 @@ public class DifferentDBSchemaTest extends BaseEnversJPAFunctionalTestCase { super.addConfigOptions(options); // Creates new schema after establishing connection options.putAll(Environment.getProperties()); - options.put(Environment.URL, options.get(Environment.URL) + ";INIT=CREATE SCHEMA IF NOT EXISTS " + SCHEMA_NAME); options.put("org.hibernate.envers.default_schema", SCHEMA_NAME); } + @Override + protected String createSecondSchema() { + return SCHEMA_NAME; + } + @Override public void configure(Ejb3Configuration cfg) { cfg.addAnnotatedClass(StrTestEntity.class); diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java index ff0a8909a9..02658301fe 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/BaseCoreFunctionalTestCase.java @@ -45,8 +45,10 @@ import org.hibernate.cfg.Configuration; import org.hibernate.cfg.Environment; import org.hibernate.cfg.Mappings; import org.hibernate.dialect.Dialect; +import org.hibernate.dialect.H2Dialect; import org.hibernate.engine.spi.SessionFactoryImplementor; import org.hibernate.engine.spi.SessionImplementor; +import org.hibernate.internal.util.StringHelper; import org.hibernate.internal.util.config.ConfigurationHelper; import org.hibernate.jdbc.AbstractReturningWork; import org.hibernate.jdbc.Work; @@ -178,6 +180,13 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase { configuration.setProperty( AvailableSettings.USE_NEW_ID_GENERATOR_MAPPINGS, "true" ); if ( createSchema() ) { configuration.setProperty( Environment.HBM2DDL_AUTO, "create-drop" ); + final String secondSchemaName = createSecondSchema(); + if ( StringHelper.isNotEmpty( secondSchemaName ) ) { + if ( !( getDialect() instanceof H2Dialect ) ) { + throw new UnsupportedOperationException( "Only H2 dialect supports creation of second schema." ); + } + Helper.createH2Schema( secondSchemaName, configuration ); + } } configuration.setProperty( Environment.DIALECT, getDialect().getClass().getName() ); return configuration; @@ -350,6 +359,14 @@ public abstract class BaseCoreFunctionalTestCase extends BaseUnitTestCase { return true; } + /** + * Feature supported only by H2 dialect. + * @return Provide not empty name to create second schema. + */ + protected String createSecondSchema() { + return null; + } + protected boolean rebuildSessionFactoryOnError() { return true; } diff --git a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/Helper.java b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/Helper.java index 151adff618..a67206a018 100644 --- a/hibernate-testing/src/main/java/org/hibernate/testing/junit4/Helper.java +++ b/hibernate-testing/src/main/java/org/hibernate/testing/junit4/Helper.java @@ -25,10 +25,13 @@ package org.hibernate.testing.junit4; import java.lang.annotation.Annotation; import java.lang.reflect.Method; +import java.util.Map; import org.junit.runners.model.FrameworkMethod; import org.junit.runners.model.TestClass; +import org.hibernate.cfg.Configuration; +import org.hibernate.cfg.Environment; import org.hibernate.testing.FailureExpected; /** @@ -98,4 +101,23 @@ public class Helper { .toString(); } + /** + * @see #createH2Schema(String, Map) + */ + public static void createH2Schema(String schemaName, Configuration cfg) { + createH2Schema( schemaName, cfg.getProperties() ); + } + + /** + * Create additional H2 schema. + * + * @param schemaName New schema name. + * @param settings Current settings. + */ + public static void createH2Schema(String schemaName, Map settings) { + settings.put( + Environment.URL, + settings.get( Environment.URL ) + ";INIT=CREATE SCHEMA IF NOT EXISTS " + schemaName + ); + } }