HHH-7549 @OneToMany support
This commit is contained in:
parent
550f19f3da
commit
1b69d460b3
|
@ -52,8 +52,6 @@ import org.hibernate.internal.util.ReflectHelper;
|
|||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.internal.util.ValueHolder;
|
||||
import org.hibernate.metamodel.internal.HibernateTypeHelper.ReflectedCollectionJavaTypes;
|
||||
import org.hibernate.metamodel.internal.source.hbm.ListAttributeSource;
|
||||
import org.hibernate.metamodel.internal.source.hbm.MapAttributeSource;
|
||||
import org.hibernate.metamodel.spi.MetadataImplementor;
|
||||
import org.hibernate.metamodel.spi.binding.AbstractPluralAttributeBinding;
|
||||
import org.hibernate.metamodel.spi.binding.AttributeBinding;
|
||||
|
@ -1002,11 +1000,12 @@ public class Binder {
|
|||
|
||||
private AbstractPluralAttributeBinding bindListAttribute(
|
||||
final AttributeBindingContainer attributeBindingContainer,
|
||||
final ListAttributeSource attributeSource,
|
||||
final PluralAttributeSource attributeSource,
|
||||
PluralAttribute attribute ) {
|
||||
if ( attribute == null ) {
|
||||
attribute = attributeBindingContainer.getAttributeContainer().createList( attributeSource.getName() );
|
||||
}
|
||||
final int base = IndexedPluralAttributeSource.class.isInstance( attributeSource ) ? IndexedPluralAttributeSource.class.cast( attributeSource ).getIndexSource().base() : 0;
|
||||
return attributeBindingContainer.makeListAttributeBinding(
|
||||
attribute,
|
||||
pluralAttributeElementNature( attributeSource ),
|
||||
|
@ -1014,7 +1013,7 @@ public class Binder {
|
|||
propertyAccessorName( attributeSource ),
|
||||
attributeSource.isIncludedInOptimisticLocking(),
|
||||
createMetaAttributeContext( attributeBindingContainer, attributeSource ),
|
||||
attributeSource.getIndexSource().base()
|
||||
base
|
||||
);
|
||||
}
|
||||
|
||||
|
@ -1115,7 +1114,7 @@ public class Binder {
|
|||
|
||||
private AbstractPluralAttributeBinding bindMapAttribute(
|
||||
final AttributeBindingContainer attributeBindingContainer,
|
||||
final MapAttributeSource attributeSource,
|
||||
final PluralAttributeSource attributeSource,
|
||||
PluralAttribute attribute ) {
|
||||
if ( attribute == null ) {
|
||||
attribute = attributeBindingContainer.getAttributeContainer().createMap( attributeSource.getName() );
|
||||
|
@ -1263,7 +1262,7 @@ public class Binder {
|
|||
case LIST:
|
||||
attributeBinding = bindListAttribute(
|
||||
attributeBindingContainer,
|
||||
(ListAttributeSource) attributeSource,
|
||||
attributeSource,
|
||||
attribute
|
||||
);
|
||||
resolvedType = resolveListType( (ListBinding) attributeBinding );
|
||||
|
@ -1271,7 +1270,7 @@ public class Binder {
|
|||
case MAP:
|
||||
attributeBinding = bindMapAttribute(
|
||||
attributeBindingContainer,
|
||||
(MapAttributeSource) attributeSource,
|
||||
attributeSource,
|
||||
attribute
|
||||
);
|
||||
resolvedType = resolveMapType( (MapBinding) attributeBinding );
|
||||
|
@ -1970,15 +1969,14 @@ public class Binder {
|
|||
return entityBinding.getHierarchyDetails().getEntityIdentifier().getAttributeBinding();
|
||||
}
|
||||
|
||||
final String explicitName = resolutionDelegate.getReferencedAttributeName();
|
||||
final String referencedAttributeName;
|
||||
if ( explicitName == null ) {
|
||||
throw new NotYetImplementedException( "Annotation-style property-ref resolution not yet implemented" );
|
||||
AttributeBinding referencedAttributeBinding;
|
||||
final String referencedAttributeName = resolutionDelegate.getReferencedAttributeName();
|
||||
if ( referencedAttributeName == null ) {
|
||||
referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( resolutionDelegate.getJoinColumns( ) );
|
||||
} else {
|
||||
referencedAttributeName = explicitName;
|
||||
referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( referencedAttributeName );
|
||||
}
|
||||
|
||||
AttributeBinding referencedAttributeBinding = attributeBindingContainer.locateAttributeBinding( referencedAttributeName );
|
||||
|
||||
if ( referencedAttributeBinding == null ) {
|
||||
referencedAttributeBinding = attributeBinding( entityBinding.getEntity().getName(), referencedAttributeName );
|
||||
|
@ -1988,7 +1986,7 @@ public class Binder {
|
|||
+ referencedAttributeBinding, bindingContexts.peek().getOrigin() );
|
||||
}
|
||||
if ( !referencedAttributeBinding.getAttribute().isSingular() ) {
|
||||
throw new MappingException( "Plural attribute key references a plural attribute; it must be plural: "
|
||||
throw new MappingException( "Plural attribute key references a plural attribute; it must not be plural: "
|
||||
+ referencedAttributeName, bindingContexts.peek().getOrigin() );
|
||||
}
|
||||
return ( SingularAttributeBinding ) referencedAttributeBinding;
|
||||
|
@ -2003,7 +2001,9 @@ public class Binder {
|
|||
}
|
||||
|
||||
final String explicitName = resolutionDelegate.getReferencedAttributeName();
|
||||
return explicitName != null ? referencedEntityBinding.locateAttributeBinding( explicitName ) :referencedEntityBinding.locateAttributeBinding(resolutionDelegate.getJoinColumns( resolutionContext ) );
|
||||
return explicitName != null
|
||||
? referencedEntityBinding.locateAttributeBinding( explicitName )
|
||||
:referencedEntityBinding.locateAttributeBinding(resolutionDelegate.getJoinColumns( resolutionContext ) );
|
||||
}
|
||||
|
||||
private EntityBinding entityBinding( final String entityName ) {
|
||||
|
|
|
@ -28,6 +28,7 @@ import java.util.Collections;
|
|||
import java.util.List;
|
||||
|
||||
import org.hibernate.annotations.OnDeleteAction;
|
||||
import org.hibernate.internal.util.StringHelper;
|
||||
import org.hibernate.metamodel.internal.source.annotations.attribute.Column;
|
||||
import org.hibernate.metamodel.internal.source.annotations.attribute.PluralAssociationAttribute;
|
||||
import org.hibernate.metamodel.spi.relational.ForeignKey;
|
||||
|
@ -82,21 +83,38 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource {
|
|||
|
||||
@Override
|
||||
public String getExplicitForeignKeyName() {
|
||||
return null;
|
||||
return attribute.getExplicitForeignKeyName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public JoinColumnResolutionDelegate getForeignKeyTargetColumnResolutionDelegate() {
|
||||
return null; //new JoinColumnResolutionDelegateImpl();
|
||||
|
||||
for ( Column joinColumn : attribute.getJoinColumnValues() ) {
|
||||
if ( StringHelper.isNotEmpty( joinColumn.getReferencedColumnName() ) ) {
|
||||
return new JoinColumnResolutionDelegateImpl( attribute );
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<RelationalValueSource> relationalValueSources() {
|
||||
// TODO
|
||||
return Collections.emptyList();
|
||||
if(attribute.getJoinColumnValues().isEmpty())return Collections.emptyList();
|
||||
List<RelationalValueSource> result = new ArrayList<RelationalValueSource>( attribute.getJoinColumnValues().size() );
|
||||
for(Column joinColumn : attribute.getJoinColumnValues()){
|
||||
result.add( new ColumnSourceImpl( attribute, null, joinColumn ) );
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static class JoinColumnResolutionDelegateImpl implements JoinColumnResolutionDelegate {
|
||||
private final PluralAssociationAttribute attribute;
|
||||
|
||||
public JoinColumnResolutionDelegateImpl(PluralAssociationAttribute attribute) {
|
||||
this.attribute = attribute;
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public List<Value> getJoinColumns(JoinColumnResolutionContext context) {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
|
@ -104,7 +122,7 @@ public class PluralAttributeKeySourceImpl implements PluralAttributeKeySource {
|
|||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
return null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -223,15 +223,8 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
}
|
||||
|
||||
protected boolean determineIsLazy(AnnotationInstance associationAnnotation) {
|
||||
boolean lazy = false;
|
||||
AnnotationValue fetchValue = associationAnnotation.value( "fetch" );
|
||||
if ( fetchValue != null ) {
|
||||
FetchType fetchType = Enum.valueOf( FetchType.class, fetchValue.asEnum() );
|
||||
if ( FetchType.LAZY.equals( fetchType ) ) {
|
||||
lazy = true;
|
||||
}
|
||||
}
|
||||
return lazy;
|
||||
FetchType fetchType = JandexHelper.getEnumValue( associationAnnotation, "fetch", FetchType.class );
|
||||
return FetchType.LAZY == fetchType;
|
||||
}
|
||||
|
||||
private String determineReferencedEntityType(AnnotationInstance associationAnnotation, Class<?> referencedAttributeType) {
|
||||
|
@ -310,12 +303,10 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
}
|
||||
|
||||
private String determineMapsId() {
|
||||
String referencedIdAttributeName;
|
||||
AnnotationInstance mapsIdAnnotation = JandexHelper.getSingleAnnotation( annotations(), JPADotNames.MAPS_ID );
|
||||
if ( mapsIdAnnotation == null ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
if ( !( Nature.MANY_TO_ONE.equals( getNature() ) || Nature.MANY_TO_ONE
|
||||
.equals( getNature() ) ) ) {
|
||||
throw new MappingException(
|
||||
|
@ -323,10 +314,7 @@ public class AssociationAttribute extends MappedAttribute {
|
|||
getContext().getOrigin()
|
||||
);
|
||||
}
|
||||
|
||||
referencedIdAttributeName = JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
|
||||
|
||||
return referencedIdAttributeName;
|
||||
return JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -75,7 +75,9 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
* Defines the column values (relational values) for this property. A mapped property can refer to multiple
|
||||
* column values in case of components or join columns etc
|
||||
*/
|
||||
private List<Column> columnValues;
|
||||
private List<Column> columnValues = new ArrayList<Column>( );
|
||||
|
||||
private List<Column> joinColumnValues = new ArrayList<Column>( );
|
||||
|
||||
/**
|
||||
* Is this property an id property (or part thereof).
|
||||
|
@ -152,6 +154,10 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
return columnValues;
|
||||
}
|
||||
|
||||
public List<Column> getJoinColumnValues(){
|
||||
return joinColumnValues;
|
||||
}
|
||||
|
||||
public boolean isId() {
|
||||
return isId;
|
||||
}
|
||||
|
@ -228,14 +234,15 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
}
|
||||
|
||||
private void checkColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
columnValues = new ArrayList<Column>();
|
||||
|
||||
// single @Column
|
||||
AnnotationInstance columnAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
JPADotNames.COLUMN
|
||||
);
|
||||
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 );
|
||||
}
|
||||
columnValues.add( new Column( columnAnnotation ) );
|
||||
}
|
||||
|
||||
|
@ -245,7 +252,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
JPADotNames.JOIN_COLUMN
|
||||
);
|
||||
if ( joinColumnAnnotation != null ) {
|
||||
columnValues.add( new Column( joinColumnAnnotation ) );
|
||||
joinColumnValues.add( new Column( joinColumnAnnotation ) );
|
||||
}
|
||||
|
||||
// @org.hibernate.annotations.Columns
|
||||
|
@ -254,6 +261,9 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
HibernateDotNames.COLUMNS
|
||||
);
|
||||
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 );
|
||||
}
|
||||
List<AnnotationInstance> columnsList = Arrays.asList(
|
||||
JandexHelper.getValue( columnsAnnotation, "value", AnnotationInstance[].class )
|
||||
);
|
||||
|
@ -272,7 +282,7 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class )
|
||||
);
|
||||
for ( AnnotationInstance annotation : columnsList ) {
|
||||
columnValues.add( new Column( annotation ) );
|
||||
joinColumnValues.add( new Column( annotation ) );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -311,6 +321,12 @@ public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
public DotName getAnnotationDotName() {
|
||||
return annotationDotName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "Nature{" +annotationDotName.toString()+
|
||||
'}';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -69,6 +69,7 @@ public class PluralAssociationAttribute extends AssociationAttribute {
|
|||
private final boolean isIndexed;
|
||||
// Used for the non-owning side of a ManyToMany relationship
|
||||
private final String inverseForeignKeyName;
|
||||
private final String explicitForeignKeyName;
|
||||
|
||||
private LazyCollectionOption lazyOption;
|
||||
|
||||
|
@ -103,6 +104,9 @@ public class PluralAssociationAttribute extends AssociationAttribute {
|
|||
public String getInverseForeignKeyName() {
|
||||
return inverseForeignKeyName;
|
||||
}
|
||||
public String getExplicitForeignKeyName(){
|
||||
return explicitForeignKeyName;
|
||||
}
|
||||
|
||||
public Caching getCaching() {
|
||||
return caching;
|
||||
|
@ -168,7 +172,21 @@ public class PluralAssociationAttribute extends AssociationAttribute {
|
|||
this.entityClassInfo = entityClassInfo;
|
||||
this.whereClause = determineWereClause();
|
||||
this.orderBy = determineOrderBy();
|
||||
this.inverseForeignKeyName = determineInverseForeignKeyName();
|
||||
|
||||
AnnotationInstance foreignKey = JandexHelper.getSingleAnnotation(
|
||||
annotations(),
|
||||
HibernateDotNames.FOREIGN_KEY
|
||||
);
|
||||
if ( foreignKey != null ) {
|
||||
explicitForeignKeyName = JandexHelper.getValue( foreignKey, "name", String.class );
|
||||
String temp = JandexHelper.getValue( foreignKey, "inverseName", String.class );
|
||||
inverseForeignKeyName = StringHelper.isNotEmpty( temp ) ? temp : null;
|
||||
}
|
||||
else {
|
||||
explicitForeignKeyName = null;
|
||||
inverseForeignKeyName = null;
|
||||
}
|
||||
|
||||
this.caching = determineCachingSettings();
|
||||
this.isExtraLazy = lazyOption == LazyCollectionOption.EXTRA;
|
||||
this.customPersister = determineCustomPersister();
|
||||
|
@ -250,22 +268,6 @@ public class PluralAssociationAttribute extends AssociationAttribute {
|
|||
}
|
||||
return entityPersisterClass;
|
||||
}
|
||||
|
||||
private String determineInverseForeignKeyName() {
|
||||
String foreignKeyName = null;
|
||||
|
||||
AnnotationInstance foreignKey = JandexHelper.getSingleAnnotation(
|
||||
annotations(),
|
||||
HibernateDotNames.FOREIGN_KEY
|
||||
);
|
||||
if ( foreignKey != null &&
|
||||
StringHelper.isNotEmpty( JandexHelper.getValue( foreignKey, "inverseName", String.class ) ) ) {
|
||||
foreignKeyName = JandexHelper.getValue( foreignKey, "inverseName", String.class );
|
||||
}
|
||||
|
||||
return foreignKeyName;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected boolean determineIsLazy(AnnotationInstance associationAnnotation) {
|
||||
boolean lazy = super.determineIsLazy( associationAnnotation );
|
||||
|
|
Loading…
Reference in New Issue