HHH-7571 Adding test for @CollectionTable

This commit is contained in:
Hardy Ferentschik 2012-09-07 11:55:33 +02:00
parent ebcc59f0a1
commit 9e8dc3017b
5 changed files with 184 additions and 90 deletions

View File

@ -1844,36 +1844,64 @@ public class Binder {
private TableSpecification createTable(
final TableSpecificationSource tableSpecSource,
final DefaultNamingStrategy defaultNamingStrategy ) {
final DefaultNamingStrategy defaultNamingStrategy) {
final LocalBindingContext bindingContext = bindingContexts.peek();
final MappingDefaults mappingDefaults = bindingContext.getMappingDefaults();
final String explicitCatalogName = tableSpecSource == null ? null : tableSpecSource.getExplicitCatalogName();
final String explicitSchemaName = tableSpecSource == null ? null : tableSpecSource.getExplicitSchemaName();
final Schema.Name schemaName =
new Schema.Name(
createIdentifier( tableSpecSource.getExplicitCatalogName(), mappingDefaults.getCatalogName() ),
createIdentifier( tableSpecSource.getExplicitSchemaName(), mappingDefaults.getSchemaName() )
createIdentifier( explicitCatalogName, mappingDefaults.getCatalogName() ),
createIdentifier( explicitSchemaName, mappingDefaults.getSchemaName() )
);
final Schema schema = metadata.getDatabase().locateSchema( schemaName );
if ( tableSpecSource instanceof TableSource ) {
TableSpecification tableSpec = null;
if ( tableSpecSource == null ) {
if ( defaultNamingStrategy == null ) {
throw new MappingException(
"An explicit name must be specified for the table",
bindingContext.getOrigin()
);
}
String tableName = defaultNamingStrategy.defaultName();
tableSpec = createTableSpecification( bindingContext, schema, tableName );
}
else if ( tableSpecSource instanceof TableSource ) {
final TableSource tableSource = ( TableSource ) tableSpecSource;
String tableName = tableSource.getExplicitTableName();
if ( tableName == null ) {
if ( defaultNamingStrategy == null ) {
throw new MappingException( "An explicit name must be specified for the table", bindingContext.getOrigin() );
throw new MappingException(
"An explicit name must be specified for the table",
bindingContext.getOrigin()
);
}
tableName = defaultNamingStrategy.defaultName();
}
tableName = quotedIdentifier( tableName );
final Identifier logicalTableId = Identifier.toIdentifier( tableName );
tableName = quotedIdentifier( bindingContext.getNamingStrategy().tableName( tableName ) );
final Identifier physicalTableId = Identifier.toIdentifier( tableName );
final Table table = schema.locateTable( logicalTableId );
return ( table == null ? schema.createTable( logicalTableId, physicalTableId ) : table );
tableSpec = createTableSpecification( bindingContext, schema, tableName );
}
final InLineViewSource inLineViewSource = ( InLineViewSource ) tableSpecSource;
return schema.createInLineView(
Identifier.toIdentifier( inLineViewSource.getLogicalName() ),
inLineViewSource.getSelectStatement()
);
else {
final InLineViewSource inLineViewSource = ( InLineViewSource ) tableSpecSource;
tableSpec = schema.createInLineView(
Identifier.toIdentifier( inLineViewSource.getLogicalName() ),
inLineViewSource.getSelectStatement()
);
}
return tableSpec;
}
private TableSpecification createTableSpecification(LocalBindingContext bindingContext, Schema schema, String tableName) {
TableSpecification tableSpec;
tableName = quotedIdentifier( tableName );
final Identifier logicalTableId = Identifier.toIdentifier( tableName );
tableName = quotedIdentifier( bindingContext.getNamingStrategy().tableName( tableName ) );
final Identifier physicalTableId = Identifier.toIdentifier( tableName );
final Table table = schema.locateTable( logicalTableId );
tableSpec = ( table == null ? schema.createTable( logicalTableId, physicalTableId ) : table );
return tableSpec;
}
private String defaultCollectionElementJavaTypeName(

View File

@ -42,7 +42,6 @@ import org.hibernate.metamodel.spi.source.PluralAttributeElementSource;
import org.hibernate.metamodel.spi.source.PluralAttributeKeySource;
import org.hibernate.metamodel.spi.source.PluralAttributeSource;
import org.hibernate.metamodel.spi.source.Sortable;
import org.hibernate.metamodel.spi.source.TableSource;
import org.hibernate.metamodel.spi.source.TableSpecificationSource;
/**
@ -50,18 +49,18 @@ import org.hibernate.metamodel.spi.source.TableSpecificationSource;
*/
public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderable, Sortable {
private final PluralAssociationAttribute attribute;
private final PluralAssociationAttribute associationAttribute;
private final Nature nature;
private final ExplicitHibernateTypeSource typeSource;
private final PluralAttributeKeySource keySource;
private final PluralAttributeElementSource elementSource;
public PluralAttributeSourceImpl(final PluralAssociationAttribute attribute) {
this.attribute = attribute;
public PluralAttributeSourceImpl(final PluralAssociationAttribute associationAttribute) {
this.associationAttribute = associationAttribute;
this.nature = resolveAttributeNature();
this.keySource = new PluralAttributeKeySourceImpl( attribute );
this.keySource = new PluralAttributeKeySourceImpl( associationAttribute );
this.elementSource = determineElementSource();
this.typeSource = new ExplicitHibernateTypeSourceImpl( attribute );
this.typeSource = new ExplicitHibernateTypeSourceImpl( associationAttribute );
}
@Override
@ -75,19 +74,19 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
}
private PluralAttributeElementSource determineElementSource() {
switch ( attribute.getNature() ) {
switch ( associationAttribute.getNature() ) {
case MANY_TO_MANY:
return new ManyToManyPluralAttributeElementSourceImpl( attribute );
return new ManyToManyPluralAttributeElementSourceImpl( associationAttribute );
case MANY_TO_ANY:
return new ManyToAnyPluralAttributeElementSourceImpl( attribute );
return new ManyToAnyPluralAttributeElementSourceImpl( associationAttribute );
case ONE_TO_MANY:
return new OneToManyPluralAttributeElementSourceImpl( attribute );
return new OneToManyPluralAttributeElementSourceImpl( associationAttribute );
case ELEMENT_COLLECTION_BASIC:
case ELEMENT_COLLECTION_EMBEDDABLE: {
return new BasicPluralAttributeElementSourceImpl( attribute );
return new BasicPluralAttributeElementSourceImpl( associationAttribute );
}
}
throw new AssertionError( "unexpected attribute nature" );
throw new AssertionError( "Unexpected attribute nature for a association:" + associationAttribute.getNature() );
}
@Override
@ -99,22 +98,13 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
public TableSpecificationSource getCollectionTableSpecificationSource() {
// todo - see org.hibernate.metamodel.internal.Binder#bindOneToManyCollectionKey
// todo - needs to cater for @CollectionTable and @JoinTable
return new TableSource() {
@Override
public String getExplicitSchemaName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getExplicitCatalogName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
@Override
public String getExplicitTableName() {
return null; //To change body of implemented methods use File | Settings | File Templates.
}
};
if ( associationAttribute.getJoinTableAnnotation() == null ) {
return null;
}
else {
return new TableSourceImpl( associationAttribute.getJoinTableAnnotation() );
}
}
@Override
@ -124,57 +114,57 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
@Override
public String getCollectionTableCheck() {
return attribute.getCheckCondition();
return associationAttribute.getCheckCondition();
}
@Override
public Caching getCaching() {
return attribute.getCaching();
return associationAttribute.getCaching();
}
@Override
public String getCustomPersisterClassName() {
return attribute.getCustomPersister();
return associationAttribute.getCustomPersister();
}
@Override
public String getWhere() {
return attribute.getWhereClause();
return associationAttribute.getWhereClause();
}
@Override
public boolean isInverse() {
return attribute.getMappedBy() != null;
return associationAttribute.getMappedBy() != null;
}
@Override
public String getCustomLoaderName() {
return attribute.getCustomLoaderName();
return associationAttribute.getCustomLoaderName();
}
@Override
public CustomSQL getCustomSqlInsert() {
return attribute.getCustomInsert();
return associationAttribute.getCustomInsert();
}
@Override
public CustomSQL getCustomSqlUpdate() {
return attribute.getCustomUpdate();
return associationAttribute.getCustomUpdate();
}
@Override
public CustomSQL getCustomSqlDelete() {
return attribute.getCustomDelete();
return associationAttribute.getCustomDelete();
}
@Override
public CustomSQL getCustomSqlDeleteAll() {
return attribute.getCustomDeleteAll();
return associationAttribute.getCustomDeleteAll();
}
@Override
public String getName() {
return attribute.getName();
return associationAttribute.getName();
}
@Override
@ -189,12 +179,12 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
@Override
public String getPropertyAccessorName() {
return attribute.getAccessType();
return associationAttribute.getAccessType();
}
@Override
public boolean isIncludedInOptimisticLocking() {
return attribute.isOptimisticLockable();
return associationAttribute.isOptimisticLockable();
}
@Override
@ -205,12 +195,12 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
@Override
public FetchMode getFetchMode() {
return attribute.getFetchMode();
return associationAttribute.getFetchMode();
}
@Override
public String getOrder() {
return attribute.getOrderBy();
return associationAttribute.getOrderBy();
}
@Override
@ -220,20 +210,20 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
@Override
public String getComparatorName() {
return attribute.getComparatorName();
return associationAttribute.getComparatorName();
}
@Override
public boolean isSorted() {
return attribute.isSorted();
return associationAttribute.isSorted();
}
@Override
public FetchTiming getFetchTiming() {
if ( attribute.isExtraLazy() ) {
if ( associationAttribute.isExtraLazy() ) {
return FetchTiming.EXTRA_DELAYED;
}
if ( attribute.isLazy() ) {
if ( associationAttribute.isLazy() ) {
return FetchTiming.DELAYED;
}
return FetchTiming.IMMEDIATE;
@ -241,17 +231,17 @@ public class PluralAttributeSourceImpl implements PluralAttributeSource, Orderab
@Override
public FetchStyle getFetchStyle() {
return attribute.getFetchStyle();
return associationAttribute.getFetchStyle();
}
private Nature resolveAttributeNature() {
if ( Map.class.isAssignableFrom( attribute.getAttributeType() ) ) {
if ( Map.class.isAssignableFrom( associationAttribute.getAttributeType() ) ) {
return PluralAttributeSource.Nature.MAP;
}
else if ( List.class.isAssignableFrom( attribute.getAttributeType() ) ) {
else if ( List.class.isAssignableFrom( associationAttribute.getAttributeType() ) ) {
return PluralAttributeSource.Nature.LIST;
}
else if ( Set.class.isAssignableFrom( attribute.getAttributeType() ) ) {
else if ( Set.class.isAssignableFrom( associationAttribute.getAttributeType() ) ) {
return PluralAttributeSource.Nature.SET;
}
else {

View File

@ -68,7 +68,7 @@ public class AssociationAttribute extends MappedAttribute {
private final boolean mapsId;
private final String referencedIdAttributeName;
private final List<Column> joinColumnValues;
private final boolean definesExplicitJoinTable;
private final AnnotationInstance joinTableAnnotation;
private AttributeTypeResolver resolver;
public static AssociationAttribute createAssociationAttribute(
@ -119,7 +119,7 @@ public class AssociationAttribute extends MappedAttribute {
this.referencedIdAttributeName = determineMapsId();
this.mapsId = referencedIdAttributeName != null;
this.definesExplicitJoinTable = determineExplicitJoinTable( annotations );
this.joinTableAnnotation = determineExplicitJoinTable( annotations );
}
public boolean isIgnoreNotFound() {
@ -162,8 +162,8 @@ public class AssociationAttribute extends MappedAttribute {
return joinColumnValues;
}
public boolean definesExplicitJoinTable() {
return definesExplicitJoinTable;
public AnnotationInstance getJoinTableAnnotation() {
return joinTableAnnotation;
}
@Override
@ -363,7 +363,8 @@ public class AssociationAttribute extends MappedAttribute {
return joinColumns;
}
private boolean determineExplicitJoinTable(Map<DotName, List<AnnotationInstance>> annotations) {
private AnnotationInstance determineExplicitJoinTable(Map<DotName, List<AnnotationInstance>> annotations) {
AnnotationInstance annotationInstance = null;
AnnotationInstance collectionTableAnnotation = JandexHelper.getSingleAnnotation(
annotations,
JPADotNames.COLLECTION_TABLE
@ -389,6 +390,7 @@ public class AssociationAttribute extends MappedAttribute {
getContext().getOrigin()
);
}
annotationInstance = collectionTableAnnotation;
}
if ( joinTableAnnotation != null ) {
@ -400,9 +402,10 @@ public class AssociationAttribute extends MappedAttribute {
getContext().getOrigin()
);
}
annotationInstance = joinTableAnnotation;
}
return collectionTableAnnotation != null || joinTableAnnotation != null;
return annotationInstance;
}
}

View File

@ -32,10 +32,17 @@ import javax.persistence.JoinTable;
import org.junit.Test;
import org.hibernate.jaxb.spi.SourceType;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.ListBinding;
import org.hibernate.metamodel.spi.relational.TableSpecification;
import org.hibernate.metamodel.spi.source.MappingException;
import org.hibernate.testing.junit4.BaseAnnotationBindingTestCase;
import org.hibernate.testing.junit4.Resources;
import static junit.framework.Assert.assertEquals;
import static junit.framework.Assert.fail;
/**
* Tests for different types of @ElementCollection mappings.
*
@ -61,10 +68,17 @@ public class ElementCollectionBindingTest extends BaseAnnotationBindingTestCase
}
}
@Test(expected = MappingException.class)
@Resources(annotatedClasses = { TestEntity.class })
@Test
public void testElementCollectionWithJoinTableThrowsException() {
getEntityBinding( TestEntity.class );
try {
sources.addAnnotatedClass( TestEntity.class );
sources.buildMetadata();
fail( "Invalid use of @JoinTable with @ElementCollection" );
}
catch ( MappingException e ) {
assertEquals( "Unexpected error origin", TestEntity.class.getName(), e.getOrigin().getName() );
assertEquals( "Unexpected type", SourceType.ANNOTATION, e.getOrigin().getType() );
}
}
@Entity
@ -86,10 +100,70 @@ public class ElementCollectionBindingTest extends BaseAnnotationBindingTestCase
}
}
@Test(expected = MappingException.class)
@Resources(annotatedClasses = { TestEntity.class })
@Test
public void testCollectionTableAndJoinTableThrowsException() {
getEntityBinding( TestEntity.class );
try {
sources.addAnnotatedClass( TestEntity2.class );
sources.buildMetadata();
fail( "Invalid use of @JoinTable AND @CollectionTable" );
}
catch ( MappingException e ) {
assertEquals( "Unexpected error origin", TestEntity2.class.getName(), e.getOrigin().getName() );
assertEquals( "Unexpected type", SourceType.ANNOTATION, e.getOrigin().getType() );
}
}
@Entity
class TestEntity3 {
@Id
private int id;
@ElementCollection
private List<String> strings;
public int getId() {
return id;
}
public List<String> getStrings() {
return strings;
}
}
@Test
@Resources(annotatedClasses = TestEntity3.class)
public void testDefaultJoinTableName() {
EntityBinding entityBinding = getEntityBinding( TestEntity3.class );
ListBinding listBinding = (ListBinding) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = listBinding.getPluralAttributeKeyBinding().getCollectionTable();
assertEquals( "Wrong default collection table name", "ElementCollectionBindingTest$TestEntity3_strings", tableSpec.getLogicalName().getText() );
}
@Entity
class TestEntity4 {
@Id
private int id;
@ElementCollection
@CollectionTable(name = "STRING_COLLECTION")
private List<String> strings;
public int getId() {
return id;
}
public List<String> getStrings() {
return strings;
}
}
@Test
@Resources(annotatedClasses = TestEntity4.class)
public void testExplicitJoinTableName() {
EntityBinding entityBinding = getEntityBinding( TestEntity4.class );
ListBinding listBinding = (ListBinding) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = listBinding.getPluralAttributeKeyBinding().getCollectionTable();
assertEquals( "Wrong default collection table name", "STRING_COLLECTION", tableSpec.getLogicalName().getText() );
}
}

View File

@ -29,8 +29,8 @@ import java.util.List;
import org.junit.After;
import org.junit.Rule;
import org.junit.Test;
import org.junit.rules.MethodRule;
import org.junit.runners.model.FrameworkMethod;
import org.junit.rules.TestRule;
import org.junit.runner.Description;
import org.junit.runners.model.Statement;
import org.hibernate.metamodel.MetadataSources;
@ -47,10 +47,10 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
protected List<Class<?>> annotatedClasses = new ArrayList<Class<?>>();
@Rule
public MethodRule buildMetaData = new MethodRule() {
public TestRule buildMetaData = new TestRule() {
@Override
public Statement apply(final Statement statement, FrameworkMethod frameworkMethod, Object o) {
return new KeepSetupFailureStatement( statement, frameworkMethod );
public Statement apply(Statement base, Description description) {
return new KeepSetupFailureStatement( base, description );
}
};
@ -74,13 +74,13 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
class KeepSetupFailureStatement extends Statement {
private final Statement origStatement;
private final FrameworkMethod origFrameworkMethod;
private final Description description;
private Throwable setupError;
private boolean expectedException;
KeepSetupFailureStatement(Statement statement, FrameworkMethod frameworkMethod) {
KeepSetupFailureStatement(Statement statement, Description description) {
this.origStatement = statement;
this.origFrameworkMethod = frameworkMethod;
this.description = description;
}
@Override
@ -104,10 +104,10 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
}
}
private void createBindings() throws Throwable {
private void createBindings() {
try {
sources = new MetadataSources( new ServiceRegistryBuilder().buildServiceRegistry() );
Resources resourcesAnnotation = origFrameworkMethod.getAnnotation( Resources.class );
Resources resourcesAnnotation = description.getAnnotation( Resources.class );
if ( resourcesAnnotation != null ) {
sources.getMetadataBuilder().with( resourcesAnnotation.cacheMode() );
@ -123,11 +123,10 @@ public abstract class BaseAnnotationBindingTestCase extends BaseUnitTestCase {
}
catch ( final Throwable t ) {
setupError = t;
Test testAnnotation = origFrameworkMethod.getAnnotation( Test.class );
Test testAnnotation = description.getAnnotation( Test.class );
Class<?> expected = testAnnotation.expected();
if ( t.getClass().equals( expected ) ) {
expectedException = true;
return;
}
}
}