HHH-4849 honor default join column names for @MapsId propertie including on ids with multiple columns

git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@18659 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
Emmanuel Bernard 2010-01-27 23:29:24 +00:00
parent 1904e02b63
commit c1fb90d575
5 changed files with 64 additions and 36 deletions

View File

@ -12,7 +12,6 @@ import org.hibernate.mapping.Component;
import org.hibernate.mapping.PersistentClass; import org.hibernate.mapping.PersistentClass;
import org.hibernate.mapping.Property; import org.hibernate.mapping.Property;
import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard
@ -46,12 +45,13 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
Component referencedComponent = (Component) referencedPersistentClass.getIdentifier(); Component referencedComponent = (Component) referencedPersistentClass.getIdentifier();
Iterator<Property> properties = referencedComponent.getPropertyIterator(); Iterator<Property> properties = referencedComponent.getPropertyIterator();
//prepare column name structure //prepare column name structure
boolean isExplicitReference = true; boolean isExplicitReference = true;
Map<String, Ejb3JoinColumn> columnByReferencedName = new HashMap<String, Ejb3JoinColumn>(joinColumns.length); Map<String, Ejb3JoinColumn> columnByReferencedName = new HashMap<String, Ejb3JoinColumn>(joinColumns.length);
for (Ejb3JoinColumn joinColumn : joinColumns) { for (Ejb3JoinColumn joinColumn : joinColumns) {
final String referencedColumnName = joinColumn.getReferencedColumn(); final String referencedColumnName = joinColumn.getReferencedColumn();
if ( BinderHelper.isDefault( referencedColumnName ) ) { if ( referencedColumnName == null || BinderHelper.isDefault( referencedColumnName ) ) {
break; break;
} }
columnByReferencedName.put( referencedColumnName, joinColumn ); columnByReferencedName.put( referencedColumnName, joinColumn );
@ -87,29 +87,40 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
value.setTypeName( referencedValue.getTypeName() ); value.setTypeName( referencedValue.getTypeName() );
value.setTypeParameters( referencedValue.getTypeParameters() ); value.setTypeParameters( referencedValue.getTypeParameters() );
final Iterator<Column> columns = referencedValue.getColumnIterator(); final Iterator<Column> columns = referencedValue.getColumnIterator();
//FIXME take care of Formula
while ( columns.hasNext() ) { if ( joinColumns[0].isNameDeferred() ) {
Column column = columns.next(); joinColumns[0].copyReferencedStructureAndCreateDefaultJoinColumns(
final Ejb3JoinColumn joinColumn; referencedPersistentClass,
String logicalColumnName = null; columns,
if ( isExplicitReference ) { value);
final String columnName = column.getName(); }
logicalColumnName = mappings.getLogicalColumnName( columnName, referencedPersistentClass.getTable() ); else {
joinColumn = columnByReferencedName.get( logicalColumnName ); //FIXME take care of Formula
while ( columns.hasNext() ) {
Column column = columns.next();
final Ejb3JoinColumn joinColumn;
String logicalColumnName = null;
if ( isExplicitReference ) {
final String columnName = column.getName();
logicalColumnName = mappings.getLogicalColumnName( columnName, referencedPersistentClass.getTable() );
joinColumn = columnByReferencedName.get( logicalColumnName );
}
else {
joinColumn = columnByReferencedName.get( "" + index );
index++;
}
if ( joinColumn == null && ! joinColumns[0].isNameDeferred() ) {
throw new AnnotationException(
isExplicitReference ?
"Unable to find column reference in the @MapsId mapping: " + logicalColumnName :
"Implicit column reference in the @MapsId mapping fails, try to use explicit referenceColumnNames: " + referencedEntityName
);
}
final String columnName = joinColumn == null || joinColumn.isNameDeferred() ? "tata_" + column.getName() : joinColumn
.getName();
value.addColumn( new Column( columnName ) );
column.setValue( value );
} }
else {
joinColumn = columnByReferencedName.get( "" + index );
index++;
}
if (joinColumn == null) {
throw new AnnotationException(
isExplicitReference ?
"Unable to find column reference in the @MapsId mapping: " + logicalColumnName :
"Implicit column reference in the @MapsId mapping fails, try to use explicit referenceColumnNames: " + referencedEntityName
);
}
value.addColumn( new Column( joinColumn.getName() ) );
column.setValue( value );
} }
component.addProperty( property ); component.addProperty( property );
} }

View File

@ -31,6 +31,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.PrimaryKeyJoinColumn; import javax.persistence.PrimaryKeyJoinColumn;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.MappingException; import org.hibernate.MappingException;
import org.hibernate.util.StringHelper; import org.hibernate.util.StringHelper;
import org.hibernate.annotations.JoinColumnOrFormula; import org.hibernate.annotations.JoinColumnOrFormula;
@ -386,6 +387,22 @@ public class Ejb3JoinColumn extends Ejb3Column {
} }
} }
public void copyReferencedStructureAndCreateDefaultJoinColumns(
PersistentClass referencedEntity, Iterator columnIterator, SimpleValue value
) {
if ( !isNameDeferred() ) {
throw new AssertionFailure( "Building implicit column but the column is not implicit" );
}
while ( columnIterator.hasNext() ) {
Column synthCol = (Column) columnIterator.next();
this.linkValueUsingDefaultColumnNaming( synthCol, referencedEntity, value );
}
//reset for the future
setMappingColumn( null );
}
public void linkValueUsingDefaultColumnNaming( public void linkValueUsingDefaultColumnNaming(
Column referencedColumn, PersistentClass referencedEntity, SimpleValue value Column referencedColumn, PersistentClass referencedEntity, SimpleValue value
) { ) {

View File

@ -27,7 +27,6 @@ import java.io.Serializable;
import java.sql.Types; import java.sql.Types;
import java.util.Calendar; import java.util.Calendar;
import java.util.Date; import java.util.Date;
import java.util.Map;
import java.util.Properties; import java.util.Properties;
import javax.persistence.Enumerated; import javax.persistence.Enumerated;
import javax.persistence.Lob; import javax.persistence.Lob;
@ -36,6 +35,9 @@ import javax.persistence.MapKeyTemporal;
import javax.persistence.Temporal; import javax.persistence.Temporal;
import javax.persistence.TemporalType; import javax.persistence.TemporalType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.hibernate.AnnotationException; import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure; import org.hibernate.AssertionFailure;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
@ -49,7 +51,6 @@ import org.hibernate.cfg.Ejb3JoinColumn;
import org.hibernate.cfg.ExtendedMappings; import org.hibernate.cfg.ExtendedMappings;
import org.hibernate.cfg.NotYetImplementedException; import org.hibernate.cfg.NotYetImplementedException;
import org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass; import org.hibernate.cfg.PkDrivenByDefaultMapsIdSecondPass;
import org.hibernate.cfg.SecondPass;
import org.hibernate.cfg.SetSimpleValueTypeSecondPass; import org.hibernate.cfg.SetSimpleValueTypeSecondPass;
import org.hibernate.mapping.SimpleValue; import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Table; import org.hibernate.mapping.Table;
@ -59,8 +60,6 @@ import org.hibernate.type.PrimitiveCharacterArrayClobType;
import org.hibernate.type.SerializableToBlobType; import org.hibernate.type.SerializableToBlobType;
import org.hibernate.type.WrappedMaterializedBlobType; import org.hibernate.type.WrappedMaterializedBlobType;
import org.hibernate.util.StringHelper; import org.hibernate.util.StringHelper;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/** /**
* @author Emmanuel Bernard * @author Emmanuel Bernard

View File

@ -16,10 +16,10 @@ public class Dependent {
DependentId id; DependentId id;
@MapsId("empPK") @MapsId("empPK")
@JoinColumns({ // @JoinColumns({
@JoinColumn(name = "FK1", referencedColumnName = "firstName"), // @JoinColumn(name = "FK1", referencedColumnName = "firstName"),
@JoinColumn(name = "FK2", referencedColumnName = "lastName") // @JoinColumn(name = "FK2", referencedColumnName = "lastName")
}) // })
@ManyToOne @ManyToOne
Employee emp; Employee emp;
} }

View File

@ -10,8 +10,8 @@ import org.hibernate.test.util.SchemaUtil;
public class DerivedIdentityIdClassParentEmbeddedIdDepTest extends TestCase { public class DerivedIdentityIdClassParentEmbeddedIdDepTest extends TestCase {
public void testManyToOne() throws Exception { public void testManyToOne() throws Exception {
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK1", getCfg() ) ); assertTrue( SchemaUtil.isColumnPresent( "Dependent", "emp_firstName", getCfg() ) );
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "FK2", getCfg() ) ); assertTrue( SchemaUtil.isColumnPresent( "Dependent", "emp_lastName", getCfg() ) );
assertTrue( SchemaUtil.isColumnPresent( "Dependent", "name", getCfg() ) ); assertTrue( SchemaUtil.isColumnPresent( "Dependent", "name", getCfg() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "firstName", getCfg() ) ); assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "firstName", getCfg() ) );
assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "lastName", getCfg() ) ); assertTrue( ! SchemaUtil.isColumnPresent( "Dependent", "lastName", getCfg() ) );
@ -42,8 +42,9 @@ public class DerivedIdentityIdClassParentEmbeddedIdDepTest extends TestCase {
@Override @Override
protected Class<?>[] getAnnotatedClasses() { protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[] { return new Class<?>[] {
Dependent.class, Employee.class,
Employee.class Dependent.class
}; };
} }
} }