HHH-7549 binding Indexed collection

This commit is contained in:
Strong Liu 2012-09-12 17:49:01 +08:00
parent b939be3157
commit ea2b9a899f
10 changed files with 89 additions and 33 deletions

View File

@ -112,8 +112,8 @@ public class ListBinder extends CollectionBinder {
PropertyHolder valueHolder = PropertyHolderBuilder.buildPropertyHolder(
this.collection,
StringHelper.qualify( this.collection.getRole(), "key" ),
(XClass) null,
(XProperty) null, propertyHolder, mappings
null,
null, propertyHolder, mappings
);
List list = (List) this.collection;
if ( !list.isOneToMany() ) indexColumn.forceNotNull();

View File

@ -1,8 +1,16 @@
package org.hibernate.metamodel.internal.source.annotations;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import org.jboss.jandex.AnnotationInstance;
import org.hibernate.metamodel.internal.source.annotations.attribute.Column;
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.spi.binding.PluralAttributeIndexBinding;
import org.hibernate.metamodel.spi.source.ExplicitHibernateTypeSource;
import org.hibernate.metamodel.spi.source.PluralAttributeIndexSource;
@ -14,15 +22,31 @@ import org.hibernate.metamodel.spi.source.RelationalValueSource;
public class PluralAttributeIndexSourceImpl implements PluralAttributeIndexSource {
private final PluralAssociationAttribute attribute;
private final IndexedPluralAttributeSourceImpl indexedPluralAttributeSource;
private final int base;
private final List<RelationalValueSource> relationalValueSources = new ArrayList<RelationalValueSource>( 1 );
public PluralAttributeIndexSourceImpl(IndexedPluralAttributeSourceImpl indexedPluralAttributeSource, PluralAssociationAttribute attribute) {
this.attribute = attribute;
this.indexedPluralAttributeSource = indexedPluralAttributeSource;
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation(
attribute.annotations(),
HibernateDotNames.INDEX_COLUMN
);
if(columnAnnotation == null){
columnAnnotation = JandexHelper.getSingleAnnotation(
attribute.annotations(),
JPADotNames.ORDER_COLUMN
);
}
this.base = columnAnnotation.value( "base" ) != null ? columnAnnotation.value( "base" )
.asInt() : 0;
Column indexColumn = new Column( columnAnnotation );
relationalValueSources.add( new ColumnValuesSourceImpl( indexColumn ) );
}
@Override
public PluralAttributeIndexBinding.Nature getNature() {
switch ( indexedPluralAttributeSource.getElementSource().getNature() ){
switch ( indexedPluralAttributeSource.getElementSource().getNature() ) {
case BASIC:
return PluralAttributeIndexBinding.Nature.BASIC;
case COMPONENT:
@ -37,17 +61,27 @@ public class PluralAttributeIndexSourceImpl implements PluralAttributeIndexSourc
@Override
public int base() {
return 0;
return base;
}
@Override
public ExplicitHibernateTypeSource explicitHibernateTypeSource() {
return new ExplicitHibernateTypeSource() {
@Override
public String getName() {
return "integer";
}
@Override
public Map<String, String> getParameters() {
return null;
}
};
}
@Override
public List<RelationalValueSource> relationalValueSources() {
return null;
return relationalValueSources;
}
@Override

View File

@ -53,7 +53,7 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource {
@Override
public List<RelationalValueSource> getValueSources() {
List<RelationalValueSource> valueSources = new ArrayList<RelationalValueSource>();
if ( !attribute.getColumnValues().isEmpty() ) {
if ( !attribute.getJoinColumnValues().isEmpty() ) {
for ( Column columnValues : attribute.getColumnValues() ) {
valueSources.add( new ColumnSourceImpl( attribute, null, columnValues ) );
}

View File

@ -352,7 +352,7 @@ public class AssociationAttribute extends MappedAttribute {
if ( !( Nature.MANY_TO_ONE.equals( getNature() ) || Nature.MANY_TO_ONE
.equals( getNature() ) ) ) {
throw new MappingException(
"@MapsId can only be specified on a many-to-one or one-to-one associations",
"@MapsId can only be specified on a many-to-one or one-to-one associations, property: "+ getRole(),
getContext().getOrigin()
);
}

View File

@ -200,7 +200,7 @@ public class BasicAttribute extends MappedAttribute {
if ( isId() || isVersioned() ) {
throw new AnnotationException(
"@OptimisticLock.exclude=true incompatible with @Id, @EmbeddedId and @Version: "
+ getName()
+ getRole()
);
}
}
@ -211,7 +211,7 @@ public class BasicAttribute extends MappedAttribute {
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "SimpleAttribute" );
sb.append( "{name=" ).append( getName() );
sb.append( "{name=" ).append( getRole() );
return sb.toString();
}
@ -295,7 +295,7 @@ public class BasicAttribute extends MappedAttribute {
}
if ( alreadyProcessedForColumn ) {
throw new AnnotationException( "Multiple definition of read/write conditions for column " + getName() );
throw new AnnotationException( "Multiple definition of read/write conditions for column " + getRole() );
}
readWrite[0] = annotationInstance.value( "read" ) == null ?
@ -322,7 +322,7 @@ public class BasicAttribute extends MappedAttribute {
if ( StringHelper.isNotEmpty( name ) ) {
generator = locateIdentifierGeneratorDefinition( name );
if ( generator == null ) {
throw new MappingException( String.format( "Unable to find named generator %s", name ), null );
throw new MappingException( String.format( "Unable to find named generator %s", getRole() ), getContext().getOrigin() );
}
}
else {

View File

@ -25,8 +25,10 @@ package org.hibernate.metamodel.internal.source.annotations.attribute;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.hibernate.AssertionFailure;
import org.hibernate.metamodel.internal.source.annotations.util.HibernateDotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
/**
@ -52,11 +54,16 @@ public class Column {
private String referencedColumnName; // from @JoinColumn
public Column(AnnotationInstance columnAnnotation) {
if ( columnAnnotation != null &&
!( JPADotNames.COLUMN.equals( columnAnnotation.name() ) || JPADotNames.JOIN_COLUMN.equals(
columnAnnotation.name()
) ) ) {
if(columnAnnotation!=null){
DotName name = columnAnnotation.name();
if(!(JPADotNames.COLUMN.equals( name )
|| JPADotNames.JOIN_COLUMN.equals( name )
|| JPADotNames.ORDER_COLUMN.equals( name )
|| HibernateDotNames.INDEX_COLUMN.equals( name )
)){
throw new AssertionFailure( "A @Column or @JoinColumn annotation needs to be passed to the constructor" );
}
}
applyColumnValues( columnAnnotation );
}

View File

@ -99,6 +99,11 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
*/
private final String checkCondition;
/**
* FQN of the attribute.
*/
private final String role;
/**
* The binding context
*/
@ -125,6 +130,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
this.isOptimisticLockable = checkOptimisticLockAnnotation();
this.checkCondition = checkCheckAnnotation();
this.naturalIdMutability = checkNaturalId();
this.role = context.getOrigin().getName() + "#" + name;
checkColumnAnnotations( annotations );
}
@ -132,6 +138,10 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
return name;
}
public String getRole(){
return role;
}
public final Class<?> getAttributeType() {
return attributeType;
}
@ -185,7 +195,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
public String toString() {
final StringBuilder sb = new StringBuilder();
sb.append( "MappedAttribute" );
sb.append( "{name='" ).append( context.getOrigin().getName() ).append( "#" ).append( name ).append( '\'' );
sb.append( "{name='" ).append( getRole() ).append( '\'' );
sb.append( '}' );
return sb.toString();
}
@ -237,8 +247,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
if ( columnAnnotation != null ) {
if ( getNature() == Nature.MANY_TO_ONE || getNature() == Nature.ONE_TO_ONE ) {
throw getContext().makeMappingException(
"@Column(s) not allowed on a " + getNature() + " property: " + getContext().getOrigin()
.getName() + "." + name
"@Column(s) not allowed on a " + getNature() + " property: " + getRole()
);
}
columnValues.add( new Column( columnAnnotation ) );
@ -252,8 +261,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
if ( columnsAnnotation != null ) {
if ( getNature() == Nature.MANY_TO_ONE || getNature() == Nature.ONE_TO_ONE ) {
throw getContext().makeMappingException(
"@Column(s) not allowed on a " + getNature() + " property: " + getContext().getOrigin()
.getName() + "." + name
"@Column(s) not allowed on a " + getNature() + " property: " + getRole()
);
}
List<AnnotationInstance> columnsList = Arrays.asList(

View File

@ -217,7 +217,7 @@ public class PluralAssociationAttribute extends AssociationAttribute {
String comparatorName = JandexHelper.getValue( sortAnnotation, "comparator", String.class );
if ( StringHelper.isEmpty( comparatorName ) ) {
throw new MappingException(
"Comparator class must be provided when using SortType.COMPARATOR.",
"Comparator class must be provided when using SortType.COMPARATOR on property: "+ getRole(),
getContext().getOrigin()
);
}
@ -230,6 +230,9 @@ public class PluralAssociationAttribute extends AssociationAttribute {
AnnotationInstance orderColumnAnnotation = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ORDER_COLUMN );
AnnotationInstance indexColumnAnnotation = JandexHelper.getSingleAnnotation( annotations, HibernateDotNames.INDEX_COLUMN );
if(orderColumnAnnotation!=null && indexColumnAnnotation!=null){
throw new MappingException( "@OrderColumn and @IndexColumn can't be used together on property: " + getRole() ,getContext().getOrigin() );
}
this.isIndexed = orderColumnAnnotation != null || indexColumnAnnotation != null;
}
@ -323,7 +326,7 @@ public class PluralAssociationAttribute extends AssociationAttribute {
if ( jpaWhereAnnotation != null && hibernateWhereAnnotation != null ) {
throw new AnnotationException(
"Cannot use sql order by clause (@org.hibernate.annotations.OrderBy) " +
"in conjunction with JPA order by clause (@java.persistence.OrderBy) on " + getName()
"in conjunction with JPA order by clause (@java.persistence.OrderBy) on " + getRole()
);
}

View File

@ -33,7 +33,9 @@ import javax.persistence.JoinTable;
import org.junit.Test;
import org.hibernate.annotations.IndexColumn;
import org.hibernate.jaxb.spi.SourceType;
import org.hibernate.metamodel.spi.binding.BagBinding;
import org.hibernate.metamodel.spi.binding.EntityBinding;
import org.hibernate.metamodel.spi.binding.ListBinding;
import org.hibernate.metamodel.spi.relational.Column;
@ -140,8 +142,8 @@ public class ElementCollectionBindingTest extends BaseAnnotationBindingTestCase
@Resources(annotatedClasses = TestEntity3.class)
public void testDefaultJoinTableName() {
EntityBinding entityBinding = getEntityBinding( TestEntity3.class );
ListBinding listBinding = ( ListBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = listBinding.getPluralAttributeKeyBinding().getCollectionTable();
BagBinding bagBinding = ( BagBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = bagBinding.getPluralAttributeKeyBinding().getCollectionTable();
assertEquals(
"Wrong default collection table name",
"ElementCollectionBindingTest$TestEntity3_strings",
@ -171,8 +173,8 @@ public class ElementCollectionBindingTest extends BaseAnnotationBindingTestCase
@Resources(annotatedClasses = TestEntity4.class)
public void testExplicitJoinTableName() {
EntityBinding entityBinding = getEntityBinding( TestEntity4.class );
ListBinding listBinding = ( ListBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = listBinding.getPluralAttributeKeyBinding().getCollectionTable();
BagBinding bagBinding = ( BagBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = bagBinding.getPluralAttributeKeyBinding().getCollectionTable();
assertEquals(
"Wrong default collection table name",
"STRING_COLLECTION",
@ -203,8 +205,8 @@ public class ElementCollectionBindingTest extends BaseAnnotationBindingTestCase
@Resources(annotatedClasses = TestEntity5.class)
public void testJoinColumnAsPartOfCollectionTable() {
EntityBinding entityBinding = getEntityBinding( TestEntity5.class );
ListBinding listBinding = ( ListBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = listBinding.getPluralAttributeKeyBinding().getCollectionTable();
BagBinding bagBinding = ( BagBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = bagBinding.getPluralAttributeKeyBinding().getCollectionTable();
Column column = tableSpec.locateColumn( "FOO" );
assertNotNull( "The join column should be named FOO", column );
}
@ -231,8 +233,8 @@ public class ElementCollectionBindingTest extends BaseAnnotationBindingTestCase
@Resources(annotatedClasses = TestEntity6.class)
public void testElementCollectionWithJoinColumn() {
EntityBinding entityBinding = getEntityBinding( TestEntity6.class );
ListBinding listBinding = ( ListBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = listBinding.getPluralAttributeKeyBinding().getCollectionTable();
BagBinding bagBinding = ( BagBinding ) entityBinding.locateAttributeBinding( "strings" );
TableSpecification tableSpec = bagBinding.getPluralAttributeKeyBinding().getCollectionTable();
Column column = tableSpec.locateColumn( "FOO" );
assertNotNull( "The join column should be named FOO", column );
}

View File

@ -13,6 +13,7 @@ import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import org.hibernate.annotations.IndexColumn;
import org.hibernate.annotations.LazyCollection;
import org.hibernate.annotations.LazyCollectionOption;
/**
@ -68,6 +69,7 @@ public class EntityWithUnidirectionalOneToMany {
@OneToMany(fetch = FetchType.EAGER)
@JoinColumn(name = "theListOwner", nullable = false)
@IndexColumn( name = "list_index")
public List<ReferencedEntity> getTheList() {
return theList;
}