HHH-8282 composite id with generator binding

This commit is contained in:
Strong Liu 2013-05-31 13:21:56 -07:00
parent dbc38e096e
commit eb9f0beeef
7 changed files with 63 additions and 26 deletions

View File

@ -264,11 +264,15 @@ public class RootEntitySourceImpl extends EntitySourceImpl implements RootEntity
public List<SingularAttributeSource> getAttributeSourcesMakingUpIdentifier() {
List<SingularAttributeSource> attributeSources = new ArrayList<SingularAttributeSource>();
for ( MappedAttribute attr : rootEntitySource.getEntityClass().getIdAttributes() ) {
SingularAttributeSource attributeSource =
attr instanceof SingularAssociationAttribute ?
new ToOneAttributeSourceImpl( (SingularAssociationAttribute) attr ) :
new SingularAttributeSourceImpl( attr );
attributeSources.add( attributeSource );
switch ( attr.getNature() ) {
case BASIC:
attributeSources.add( new SingularAttributeSourceImpl( attr ) );
break;
case MANY_TO_ONE:
case ONE_TO_ONE:
//others??
attributeSources.add( new ToOneAttributeSourceImpl( (SingularAssociationAttribute) attr ) );
}
}
return attributeSources;
}

View File

@ -520,12 +520,10 @@ public class ConfiguredClass {
annotations,
getLocalBindingContext()
);
if ( attribute.isId() ) {
if(attribute.isId()){
idAttributeMap.put( attributeName, attribute );
}
else {
associationAttributeMap.put( attributeName, attribute );
}
associationAttributeMap.put( attributeName, attribute );
break;
}
case ELEMENT_COLLECTION_EMBEDDABLE:

View File

@ -25,6 +25,7 @@ package org.hibernate.metamodel.spi.binding;
import java.io.Serializable;
import java.util.List;
import java.util.Map;
import java.util.Properties;
import org.hibernate.MappingException;
@ -40,6 +41,7 @@ import org.hibernate.metamodel.spi.relational.Column;
import org.hibernate.metamodel.spi.relational.Schema;
import org.hibernate.metamodel.spi.relational.Table;
import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.property.Setter;
import static org.hibernate.id.EntityIdentifierNature.AGGREGATED_COMPOSITE;
import static org.hibernate.id.EntityIdentifierNature.NON_AGGREGATED_COMPOSITE;
@ -256,23 +258,12 @@ public class EntityIdentifier {
return getAttributeBinding().equals( attributeBinding );
}
public abstract IdentifierGenerator createIdentifierGenerator(IdentifierGeneratorFactory factory, Properties properties);
}
private class SimpleAttributeIdentifierBindingImpl extends EntityIdentifierBinding {
SimpleAttributeIdentifierBindingImpl(
SingularNonAssociationAttributeBinding identifierAttributeBinding,
IdGenerator idGenerator,
String unsavedValue) {
super( SIMPLE, identifierAttributeBinding, idGenerator, unsavedValue );
}
@Override
public IdentifierGenerator createIdentifierGenerator(
IdentifierGeneratorFactory identifierGeneratorFactory,
Properties properties) {
final List<RelationalValueBinding> relationalValueBindings =
getAttributeBinding().getRelationalValueBindings();
// TODO: If multiple @Column annotations exist within an id's
// @Columns, we need a more solid solution than simply grabbing
// the first one to get the TableSpecification.
@ -334,6 +325,16 @@ public class EntityIdentifier {
}
}
private class SimpleAttributeIdentifierBindingImpl extends EntityIdentifierBinding {
SimpleAttributeIdentifierBindingImpl(
SingularNonAssociationAttributeBinding identifierAttributeBinding,
IdGenerator idGenerator,
String unsavedValue) {
super( SIMPLE, identifierAttributeBinding, idGenerator, unsavedValue );
}
}
private String resolveTableNames(Dialect dialect, EntityBinding entityBinding) {
EntityBinding[] ebs = entityBinding.getPostOrderSubEntityBindingClosure();
StringBuilder tableNames = new StringBuilder();
@ -385,6 +386,13 @@ public class EntityIdentifier {
throw new AssertionError( "Creating an identifier generator for a component on a subclass." );
}
final EntityIdentifier entityIdentifier = entityBinding.getHierarchyDetails().getEntityIdentifier();
final boolean hasCustomGenerator = ! "assigned".equals( getIdGenerator().getStrategy() );
if ( hasCustomGenerator ) {
return super.createIdentifierGenerator(
factory, properties
);
}
final Class entityClass = entityBinding.getEntity().getClassReference();
final Class attributeDeclarer; // what class is the declarer of the composite pk attributes
// IMPL NOTE : See the javadoc discussion on CompositeNestedGeneratedValueGenerator wrt the
@ -402,6 +410,35 @@ public class EntityIdentifier {
}
}
private static class ValueGenerationPlan implements CompositeNestedGeneratedValueGenerator.GenerationPlan {
private final String propertyName;
private final IdentifierGenerator subGenerator;
private final Setter injector;
public ValueGenerationPlan(
String propertyName,
IdentifierGenerator subGenerator,
Setter injector) {
this.propertyName = propertyName;
this.subGenerator = subGenerator;
this.injector = injector;
}
/**
* {@inheritDoc}
*/
public void execute(SessionImplementor session, Object incomingObject, Object injectionContext) {
final Object generatedValue = subGenerator.generate( session, incomingObject );
injector.set( injectionContext, generatedValue, session.getFactory() );
}
public void registerPersistentGenerators(Map generatorMap) {
if ( PersistentIdentifierGenerator.class.isInstance( subGenerator ) ) {
generatorMap.put( ( (PersistentIdentifierGenerator) subGenerator ).generatorKey(), subGenerator );
}
}
}
private class NonAggregatedCompositeIdentifierBindingImpl extends EntityIdentifierBinding {
private final Class<?> externalAggregatingClass;
private final String externalAggregatingPropertyAccessorName;

View File

@ -27,7 +27,7 @@ import java.util.List;
/**
* Additional contract describing the source of an identifier mapping whose {@link #getNature() nature} is
* {@link org.hibernate.id.EntityIdentifierNature#SIMPLE simple}.
* {@link org.hibernate.id.EntityIdentifierNature#NON_AGGREGATED_COMPOSITE }.
*
* @author Steve Ebersole
*/

View File

@ -26,7 +26,6 @@ package org.hibernate.test.annotations.derivedidentities.bidirectional;
import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
import static org.junit.Assert.assertEquals;

View File

@ -31,7 +31,6 @@ import org.junit.Test;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.testing.FailureExpectedWithNewMetamodel;
import org.hibernate.testing.TestForIssue;
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
@ -52,7 +51,6 @@ import static org.junit.Assert.assertTrue;
* @author Jacob Robertson
*/
@TestForIssue( jiraKey = "HHH-2060" )
@FailureExpectedWithNewMetamodel
public class CompositeIdWithGeneratorTest extends BaseCoreFunctionalTestCase {
private DateFormat df = SimpleDateFormat.getDateTimeInstance( DateFormat.LONG, DateFormat.LONG );

View File

@ -25,6 +25,7 @@ package org.hibernate.test.cid;
import java.io.Serializable;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.id.IdentifierGenerator;
import org.hibernate.id.IdentityGenerator;
/**
@ -32,7 +33,7 @@ import org.hibernate.id.IdentityGenerator;
*
* @author Jacob Robertson
*/
public class PurchaseRecordIdGenerator extends IdentityGenerator {
public class PurchaseRecordIdGenerator implements IdentifierGenerator {
private static int nextPurchaseNumber = 2;
private static int nextPurchaseSequence = 3;