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.Property;
import org.hibernate.mapping.SimpleValue;
import org.hibernate.mapping.Value;
/**
* @author Emmanuel Bernard
@ -46,12 +45,13 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
Component referencedComponent = (Component) referencedPersistentClass.getIdentifier();
Iterator<Property> properties = referencedComponent.getPropertyIterator();
//prepare column name structure
boolean isExplicitReference = true;
Map<String, Ejb3JoinColumn> columnByReferencedName = new HashMap<String, Ejb3JoinColumn>(joinColumns.length);
for (Ejb3JoinColumn joinColumn : joinColumns) {
final String referencedColumnName = joinColumn.getReferencedColumn();
if ( BinderHelper.isDefault( referencedColumnName ) ) {
if ( referencedColumnName == null || BinderHelper.isDefault( referencedColumnName ) ) {
break;
}
columnByReferencedName.put( referencedColumnName, joinColumn );
@ -87,29 +87,40 @@ public class CopyIdentifierComponentSecondPass implements SecondPass {
value.setTypeName( referencedValue.getTypeName() );
value.setTypeParameters( referencedValue.getTypeParameters() );
final Iterator<Column> columns = referencedValue.getColumnIterator();
//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 );
if ( joinColumns[0].isNameDeferred() ) {
joinColumns[0].copyReferencedStructureAndCreateDefaultJoinColumns(
referencedPersistentClass,
columns,
value);
}
else {
//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 );
}

View File

@ -31,6 +31,7 @@ import javax.persistence.JoinColumn;
import javax.persistence.PrimaryKeyJoinColumn;
import org.hibernate.AnnotationException;
import org.hibernate.AssertionFailure;
import org.hibernate.MappingException;
import org.hibernate.util.StringHelper;
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(
Column referencedColumn, PersistentClass referencedEntity, SimpleValue value
) {

View File

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

View File

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

View File

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