HHH-9961 - Ejb3JoinColumn does not use PhysicalNamingStrategy

This commit is contained in:
Steve Ebersole 2015-07-31 12:52:01 -05:00
parent c1af6433c2
commit 923ecb8e2c
4 changed files with 185 additions and 13 deletions

View File

@ -23,6 +23,7 @@ import org.hibernate.annotations.JoinFormula;
import org.hibernate.annotations.common.reflection.XClass; import org.hibernate.annotations.common.reflection.XClass;
import org.hibernate.boot.model.naming.EntityNaming; import org.hibernate.boot.model.naming.EntityNaming;
import org.hibernate.boot.model.naming.Identifier; import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.ImplicitBasicColumnNameSource;
import org.hibernate.boot.model.naming.ImplicitJoinColumnNameSource; import org.hibernate.boot.model.naming.ImplicitJoinColumnNameSource;
import org.hibernate.boot.model.naming.ImplicitNamingStrategy; import org.hibernate.boot.model.naming.ImplicitNamingStrategy;
import org.hibernate.boot.model.naming.ImplicitPrimaryKeyJoinColumnNameSource; import org.hibernate.boot.model.naming.ImplicitPrimaryKeyJoinColumnNameSource;
@ -495,7 +496,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
final ImplicitNamingStrategy implicitNamingStrategy = getBuildingContext().getBuildingOptions().getImplicitNamingStrategy(); final ImplicitNamingStrategy implicitNamingStrategy = getBuildingContext().getBuildingOptions().getImplicitNamingStrategy();
final PhysicalNamingStrategy physicalNamingStrategy = getBuildingContext().getBuildingOptions().getPhysicalNamingStrategy(); final PhysicalNamingStrategy physicalNamingStrategy = getBuildingContext().getBuildingOptions().getPhysicalNamingStrategy();
String columnName; Identifier columnIdentifier;
boolean mappedBySide = mappedByTableName != null || mappedByPropertyName != null; boolean mappedBySide = mappedByTableName != null || mappedByPropertyName != null;
boolean ownerSide = getPropertyName() != null; boolean ownerSide = getPropertyName() != null;
@ -505,8 +506,6 @@ public class Ejb3JoinColumn extends Ejb3Column {
: logicalReferencedColumn; : logicalReferencedColumn;
if ( mappedBySide ) { if ( mappedBySide ) {
final Identifier columnIdentifier;
// NOTE : While it is completely misleading here to allow for the combination // NOTE : While it is completely misleading here to allow for the combination
// of a "JPA ElementCollection" to be mappedBy, the code that uses this // of a "JPA ElementCollection" to be mappedBy, the code that uses this
// class relies on this behavior for handling the inverse side of // class relies on this behavior for handling the inverse side of
@ -579,7 +578,8 @@ public class Ejb3JoinColumn extends Ejb3Column {
return null; return null;
} }
final PersistentClass mappedByEntityBinding = getBuildingContext().getMetadataCollector().getEntityBinding( mappedByEntityName ); final PersistentClass mappedByEntityBinding = getBuildingContext().getMetadataCollector()
.getEntityBinding( mappedByEntityName );
final Property mappedByProperty = mappedByEntityBinding.getProperty( mappedByPropertyName ); final Property mappedByProperty = mappedByEntityBinding.getProperty( mappedByPropertyName );
final SimpleValue value = (SimpleValue) mappedByProperty.getValue(); final SimpleValue value = (SimpleValue) mappedByProperty.getValue();
final Iterator<Selectable> selectableValues = value.getColumnIterator(); final Iterator<Selectable> selectableValues = value.getColumnIterator();
@ -626,10 +626,9 @@ public class Ejb3JoinColumn extends Ejb3Column {
} }
); );
columnName = columnIdentifier.render();
//one element was quoted so we quote //one element was quoted so we quote
if ( isRefColumnQuoted || StringHelper.isQuoted( mappedByTableName ) ) { if ( isRefColumnQuoted || StringHelper.isQuoted( mappedByTableName ) ) {
columnName = StringHelper.quote( columnName ); columnIdentifier = Identifier.quote( columnIdentifier );
} }
} }
else if ( ownerSide ) { else if ( ownerSide ) {
@ -647,7 +646,8 @@ public class Ejb3JoinColumn extends Ejb3Column {
else { else {
implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ENTITY_COLLECTION; implicitNamingNature = ImplicitJoinColumnNameSource.Nature.ENTITY_COLLECTION;
} }
Identifier columnNameIdentifier = getBuildingContext().getBuildingOptions().getImplicitNamingStrategy().determineJoinColumnName(
columnIdentifier = getBuildingContext().getBuildingOptions().getImplicitNamingStrategy().determineJoinColumnName(
new ImplicitJoinColumnNameSource() { new ImplicitJoinColumnNameSource() {
private final EntityNaming entityNaming = new EntityNaming() { private final EntityNaming entityNaming = new EntityNaming() {
@Override @Override
@ -705,11 +705,11 @@ public class Ejb3JoinColumn extends Ejb3Column {
} }
} }
); );
//one element was quoted so we quote //one element was quoted so we quote
if ( isRefColumnQuoted || StringHelper.isQuoted( logicalTableName ) ) { if ( isRefColumnQuoted || StringHelper.isQuoted( logicalTableName ) ) {
Identifier.quote( columnNameIdentifier ); columnIdentifier = Identifier.quote( columnIdentifier );
} }
columnName = columnNameIdentifier.render();
} }
else { else {
final Identifier logicalTableName = database.toIdentifier( final Identifier logicalTableName = database.toIdentifier(
@ -717,7 +717,7 @@ public class Ejb3JoinColumn extends Ejb3Column {
); );
// is an intra-entity hierarchy table join so copy the name by default // is an intra-entity hierarchy table join so copy the name by default
Identifier columnIdentifier = implicitNamingStrategy.determinePrimaryKeyJoinColumnName( columnIdentifier = implicitNamingStrategy.determinePrimaryKeyJoinColumnName(
new ImplicitPrimaryKeyJoinColumnNameSource() { new ImplicitPrimaryKeyJoinColumnNameSource() {
@Override @Override
public MetadataBuildingContext getBuildingContext() { public MetadataBuildingContext getBuildingContext() {
@ -739,11 +739,10 @@ public class Ejb3JoinColumn extends Ejb3Column {
if ( !columnIdentifier.isQuoted() && ( isRefColumnQuoted || logicalTableName.isQuoted() ) ) { if ( !columnIdentifier.isQuoted() && ( isRefColumnQuoted || logicalTableName.isQuoted() ) ) {
columnIdentifier = Identifier.quote( columnIdentifier ); columnIdentifier = Identifier.quote( columnIdentifier );
} }
columnName = columnIdentifier.render();
} }
return columnName; return physicalNamingStrategy.toPhysicalColumnName( columnIdentifier, database.getJdbcEnvironment() )
.render( database.getJdbcEnvironment().getDialect() );
} }
/** /**

View File

@ -0,0 +1,63 @@
/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.namingstrategy.ejb3joincolumn;
import javax.persistence.Access;
import javax.persistence.AccessType;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
/**
* @author Anton Wimmer
* @author Steve Ebersole
*/
@Entity
//@Immutable
//@Cacheable
//@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
//@SuppressWarnings("serial")
public class Language {
@Id
@Access(AccessType.PROPERTY)
private Long id = null;
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
// @Column(unique = true)
// @Lob
// @Type(type = "org.hibernate.type.TextType")
private String name;
@ManyToOne(optional = true)
@JoinColumn
private Language fallBack;
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Language getFallBack() {
return fallBack;
}
public void setFallBack(Language fallBack) {
this.fallBack = fallBack;
}
}

View File

@ -0,0 +1,40 @@
/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.namingstrategy.ejb3joincolumn;
import org.hibernate.boot.model.naming.Identifier;
import org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl;
import org.hibernate.engine.jdbc.env.spi.JdbcEnvironment;
/**
* @author Anton Wimmer
* @author Steve Ebersole
*/
public class PhysicalNamingStrategyImpl extends PhysicalNamingStrategyStandardImpl {
/**
* Singleton access
*/
public static final PhysicalNamingStrategyImpl INSTANCE = new PhysicalNamingStrategyImpl();
@Override
public Identifier toPhysicalTableName(Identifier name, JdbcEnvironment jdbcEnvironment) {
return Identifier.toIdentifier(makeCleanIdentifier("tbl_" + name.getText()), name.isQuoted());
}
@Override
public Identifier toPhysicalColumnName(Identifier name, JdbcEnvironment jdbcEnvironment) {
if ( name.getText().equals("DTYPE") ) {
return name;
}
return Identifier.toIdentifier(makeCleanIdentifier("c_" + name.getText()), name.isQuoted());
}
private String makeCleanIdentifier(String s) {
return s.substring(0, Math.min(s.length(), 63)).toLowerCase();
}
}

View File

@ -0,0 +1,70 @@
/*
* 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 <http://www.gnu.org/licenses/lgpl-2.1.html>.
*/
package org.hibernate.test.namingstrategy.ejb3joincolumn;
import java.util.Iterator;
import java.util.Locale;
import org.hibernate.boot.Metadata;
import org.hibernate.boot.MetadataBuilder;
import org.hibernate.boot.MetadataSources;
import org.hibernate.boot.model.naming.ImplicitNamingStrategyJpaCompliantImpl;
import org.hibernate.boot.registry.StandardServiceRegistry;
import org.hibernate.boot.registry.StandardServiceRegistryBuilder;
import org.hibernate.boot.spi.MetadataImplementor;
import org.hibernate.cfg.Environment;
import org.hibernate.mapping.Column;
import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.junit.Test;
import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertTrue;
/**
* Tests {@link org.hibernate.cfg.Ejb3JoinColumn} and {@link org.hibernate.boot.model.naming.PhysicalNamingStrategy}
* interaction
*
* @author Anton Wimmer
* @author Steve Ebersole
*/
public class Tests extends BaseUnitTestCase {
@Test
@TestForIssue( jiraKey = "HHH-9961" )
public void testJpaJoinColumnPhysicalNaming() {
final StandardServiceRegistry ssr = new StandardServiceRegistryBuilder()
.applySettings( Environment.getProperties() )
.build();
try {
final MetadataSources metadataSources = new MetadataSources( ssr );
metadataSources.addAnnotatedClass( Language.class );
final MetadataBuilder metadataBuilder = metadataSources.getMetadataBuilder();
metadataBuilder.applyImplicitNamingStrategy( ImplicitNamingStrategyJpaCompliantImpl.INSTANCE );
metadataBuilder.applyPhysicalNamingStrategy( PhysicalNamingStrategyImpl.INSTANCE );
final Metadata metadata = metadataBuilder.build();
( ( MetadataImplementor) metadata ).validate();
final PersistentClass languageBinding = metadata.getEntityBinding( Language.class.getName() );
final Property property = languageBinding.getProperty( "fallBack" );
Iterator itr = property.getValue().getColumnIterator();
assertTrue( itr.hasNext() );
final Column column = (Column) itr.next();
assertFalse( itr.hasNext() );
assertEquals( "C_FALLBACK_ID", column.getName().toUpperCase( Locale.ROOT ) );
}
finally {
StandardServiceRegistryBuilder.destroy( ssr );
}
}
}