HHH-7436 Finished basic M2M annotation source element handling

This commit is contained in:
Brett Meyer 2012-12-21 18:49:26 -05:00
parent 9831670567
commit e4e8f5dc61
6 changed files with 90 additions and 81 deletions

View File

@ -57,21 +57,9 @@ public ManyToManyPluralAttributeElementSourceImpl(
PluralAssociationAttribute associationAttribute) {
this.associationAttribute = associationAttribute;
for ( Column column : associationAttribute.getJoinColumnValues() ) {
relationalValueSources.add( new ColumnSourceImpl(
associationAttribute, null, column ) );
}
for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
relationalValueSources.add( new ColumnSourceImpl(
associationAttribute, null, column ) );
}
for ( Column column : associationAttribute.getJoinColumnValues() ) {
if ( column.getReferencedColumnName() != null ) {
referencedColumnNames.add( column.getReferencedColumnName() );
}
}
for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
if ( column.getReferencedColumnName() != null ) {
referencedColumnNames.add( column.getReferencedColumnName() );
}
@ -116,7 +104,8 @@ public boolean isNotFoundAnException() {
@Override
public String getExplicitForeignKeyName() {
return associationAttribute.getInverseForeignKeyName();
// TODO: If inverse, does getInverseForeignKeyName need to be handled?
return associationAttribute.getExplicitForeignKeyName();
}
@Override
@ -166,8 +155,7 @@ public boolean areValuesNullableByDefault() {
return false;
}
// TODO: This obviously won't work. We need a new way to handle
// inverse foreign key resolution.
// TODO: This needs reworked.
public class AnnotationJoinColumnResolutionDelegate
implements ForeignKeyContributingSource.JoinColumnResolutionDelegate {
private final String logicalJoinTableName;
@ -191,18 +179,6 @@ public List<Value> getJoinColumns(JoinColumnResolutionContext context) {
);
values.add( resolvedColumn );
}
// for ( Column column : associationAttribute.getInverseJoinColumnValues() ) {
// if ( column.getReferencedColumnName() == null ) {
// return context.resolveRelationalValuesForAttribute( null );
// }
// org.hibernate.metamodel.spi.relational.Column resolvedColumn = context.resolveColumn(
// column.getReferencedColumnName(),
// logicalJoinTableName,
// null,
// null
// );
// values.add( resolvedColumn );
// }
return values;
}

View File

@ -29,17 +29,14 @@
import java.util.List;
import java.util.Map;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.FetchType;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.DotName;
import org.jboss.logging.Logger;
import org.hibernate.annotations.FetchMode;
import org.hibernate.annotations.LazyToOneOption;
import org.hibernate.annotations.NotFoundAction;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.engine.FetchStyle;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.util.StringHelper;
@ -53,6 +50,12 @@
import org.hibernate.metamodel.internal.source.annotations.util.JPADotNames;
import org.hibernate.metamodel.internal.source.annotations.util.JandexHelper;
import org.hibernate.metamodel.spi.source.MappingException;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationValue;
import org.jboss.jandex.ClassInfo;
import org.jboss.jandex.DotName;
import org.jboss.jandex.Index;
import org.jboss.logging.Logger;
/**
* Represents an association attribute.
@ -78,8 +81,8 @@ public class AssociationAttribute extends MappedAttribute {
private final FetchStyle fetchStyle;
private final boolean mapsId;
private final String referencedIdAttributeName;
private final List<Column> joinColumnValues;
private final List<Column> inverseJoinColumnValues;
private ArrayList<Column> joinColumnValues = new ArrayList<Column>();
private ArrayList<Column> inverseJoinColumnValues = new ArrayList<Column>();
private final AnnotationInstance joinTableAnnotation;
private AttributeTypeResolver resolver;
@ -126,8 +129,11 @@ public static AssociationAttribute createAssociationAttribute(
this.isOrphanRemoval = determineOrphanRemoval( associationAnnotation );
this.cascadeTypes = determineCascadeTypes( associationAnnotation );
this.hibernateCascadeTypes = determineHibernateCascadeTypes( annotations );
this.joinColumnValues = determineJoinColumnAnnotations( annotations );
this.inverseJoinColumnValues = determineInverseJoinColumnAnnotations( annotations );
determineJoinColumnAnnotations( annotations );
determineJoinTableAnnotations( annotations, referencedAttributeType );
joinColumnValues.trimToSize();
inverseJoinColumnValues.trimToSize();
this.fetchStyle = determineFetchStyle();
this.referencedIdAttributeName = determineMapsId();
@ -416,16 +422,14 @@ private String determineMapsId() {
return JandexHelper.getValue( mapsIdAnnotation, "value", String.class );
}
private List<Column> determineJoinColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
ArrayList<Column> joinColumns = new ArrayList<Column>();
private void determineJoinColumnAnnotations(Map<DotName, List<AnnotationInstance>> annotations) {
// single @JoinColumn
AnnotationInstance joinColumnAnnotation = JandexHelper.getSingleAnnotation(
annotations,
JPADotNames.JOIN_COLUMN
);
if ( joinColumnAnnotation != null ) {
joinColumns.add( new Column( joinColumnAnnotation ) );
joinColumnValues.add( new Column( joinColumnAnnotation ) );
}
// @JoinColumns
@ -438,7 +442,7 @@ private List<Column> determineJoinColumnAnnotations(Map<DotName, List<Annotation
JandexHelper.getValue( joinColumnsAnnotation, "value", AnnotationInstance[].class )
);
for ( AnnotationInstance annotation : columnsList ) {
joinColumns.add( new Column( annotation ) );
joinColumnValues.add( new Column( annotation ) );
}
}
@ -452,47 +456,59 @@ private List<Column> determineJoinColumnAnnotations(Map<DotName, List<Annotation
JandexHelper.getValue( collectionTableAnnotation, "joinColumns", AnnotationInstance[].class )
);
for ( AnnotationInstance annotation : columnsList ) {
joinColumns.add( new Column( annotation ) );
joinColumnValues.add( new Column( annotation ) );
}
}
}
private void determineJoinTableAnnotations(
Map<DotName, List<AnnotationInstance>> annotations,
Class<?> referencedAttributeType ) {
boolean isJpaInverse = mappedBy != null;
// If JPA and 'mappedBy' (inverse side), override the annotations
// with the owning side.
if ( isJpaInverse ) {
// TODO: Pull some of this into JandexHelper.
Index index = JandexHelper.indexForClass(
getContext().getServiceRegistry().getService(
ClassLoaderService.class ), referencedAttributeType );
ClassInfo classInfo = index.getClassByName( DotName.createSimple(
referencedAttributeType.getName() ) );
annotations = JandexHelper.getMemberAnnotations(
classInfo, getMappedBy(), getContext().getServiceRegistry() );
}
// @JoinColumn as part of @JoinTable
AnnotationInstance joinTableAnnotation = JandexHelper.getSingleAnnotation(
annotations,
JPADotNames.JOIN_TABLE
);
if(joinTableAnnotation != null) {
if (joinTableAnnotation != null) {
List<AnnotationInstance> columnsList = Arrays.asList(
JandexHelper.getValue( joinTableAnnotation, "joinColumns", AnnotationInstance[].class )
);
for ( AnnotationInstance annotation : columnsList ) {
joinColumns.add( new Column( annotation ) );
}
}
joinColumns.trimToSize();
return joinColumns;
}
private List<Column> determineInverseJoinColumnAnnotations(
Map<DotName, List<AnnotationInstance>> annotations) {
ArrayList<Column> inverseJoinColumns = new ArrayList<Column>();
// @JoinColumn as part of @JoinTable
AnnotationInstance joinTableAnnotation = JandexHelper
.getSingleAnnotation( annotations, JPADotNames.JOIN_TABLE );
if(joinTableAnnotation != null) {
List<AnnotationInstance> columnsList = Arrays.asList(
JandexHelper.getValue( joinTableAnnotation,
"inverseJoinColumns", AnnotationInstance[].class )
List<AnnotationInstance> inverseColumnsList = Arrays.asList(
JandexHelper.getValue( joinTableAnnotation, "inverseJoinColumns", AnnotationInstance[].class )
);
// If the mappedBy inverse, flipped. Confused yet?
for ( AnnotationInstance annotation : columnsList ) {
inverseJoinColumns.add( new Column( annotation ) );
if ( isJpaInverse ) {
inverseJoinColumnValues.add( new Column( annotation ) );
} else {
joinColumnValues.add( new Column( annotation ) );
}
}
for ( AnnotationInstance annotation : inverseColumnsList ) {
if ( isJpaInverse ) {
joinColumnValues.add( new Column( annotation ) );
} else {
inverseJoinColumnValues.add( new Column( annotation ) );
}
}
}
inverseJoinColumns.trimToSize();
return inverseJoinColumns;
}
private AnnotationInstance determineExplicitJoinTable(Map<DotName, List<AnnotationInstance>> annotations) {

View File

@ -453,7 +453,7 @@ private void createMappedAttribute(Member member, ResolvedTypeWithMembers resolv
Class<?> attributeType = resolvedMember.getType().getErasedType();
Class<?> referencedCollectionType = resolveCollectionValuedReferenceType( resolvedMember );
final Map<DotName, List<AnnotationInstance>> annotations = JandexHelper.getMemberAnnotations(
classInfo, member.getName()
classInfo, member.getName(), localBindingContext.getServiceRegistry()
);
MappedAttribute.Nature attributeNature = determineAttributeNature(

View File

@ -24,9 +24,11 @@
package org.hibernate.metamodel.internal.source.annotations.util;
import java.beans.Introspector;
import java.beans.PropertyDescriptor;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Array;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
@ -34,6 +36,10 @@
import java.util.List;
import java.util.Map;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
import org.hibernate.service.ServiceRegistry;
import org.jboss.jandex.AnnotationInstance;
import org.jboss.jandex.AnnotationTarget;
import org.jboss.jandex.AnnotationValue;
@ -45,10 +51,6 @@
import org.jboss.jandex.MethodInfo;
import org.jboss.jandex.Type;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException;
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
/**
* Utility methods for working with the jandex annotation index.
*
@ -328,7 +330,8 @@ public static Index indexForClass(ClassLoaderService classLoaderService, Class<?
return indexer.complete();
}
public static Map<DotName, List<AnnotationInstance>> getMemberAnnotations(ClassInfo classInfo, String name) {
public static Map<DotName, List<AnnotationInstance>> getMemberAnnotations(
ClassInfo classInfo, String name, ServiceRegistry serviceRegistry ) {
if ( classInfo == null ) {
throw new IllegalArgumentException( "classInfo cannot be null" );
}
@ -336,7 +339,23 @@ public static Map<DotName, List<AnnotationInstance>> getMemberAnnotations(ClassI
if ( name == null ) {
throw new IllegalArgumentException( "name cannot be null" );
}
// Allow a property name to be used even if the entity uses method access.
// TODO: Is this reliable? Is there a better way to do it?
String getterName = "";
try {
Class<?> beanClass = serviceRegistry.getService(
ClassLoaderService.class ).classForName(
classInfo.name().toString() );
Method getter = new PropertyDescriptor(name, beanClass)
.getReadMethod();
if ( getter != null ) {
getterName = getter.getName();
}
} catch ( Exception e ) {
// do nothing
}
Map<DotName, List<AnnotationInstance>> annotations = new HashMap<DotName, List<AnnotationInstance>>();
for ( List<AnnotationInstance> annotationList : classInfo.annotations().values() ) {
for ( AnnotationInstance instance : annotationList ) {
@ -347,7 +366,8 @@ public static Map<DotName, List<AnnotationInstance>> getMemberAnnotations(ClassI
else if ( instance.target() instanceof MethodInfo ) {
targetName = ( (MethodInfo) instance.target() ).name();
}
if ( targetName != null && name.equals( targetName ) ) {
if ( targetName != null && ( name.equals( targetName )
|| getterName.equals( targetName ) ) ) {
addAnnotationToMap( instance, annotations );
}
}

View File

@ -24,7 +24,6 @@
package org.hibernate.metamodel.spi.source;
import java.util.Collection;
import java.util.List;
/**
* @author Steve Ebersole
@ -37,8 +36,6 @@ public interface ManyToManyPluralAttributeElementSource
public Collection<String> getReferencedColumnNames();
public List<RelationalValueSource> relationalValueSources(); // these describe the "outgoing" link
public boolean isNotFoundAnException();
public String getExplicitForeignKeyName();

View File

@ -85,7 +85,7 @@ class Foo {
ClassInfo classInfo = index.getClassByName( DotName.createSimple( Foo.class.getName() ) );
Map<DotName, List<AnnotationInstance>> memberAnnotations = JandexHelper.getMemberAnnotations(
classInfo, "bar"
classInfo, "bar", serviceRegistry
);
assertTrue(
"property bar should defines @Column annotation",
@ -96,7 +96,7 @@ class Foo {
memberAnnotations.containsKey( DotName.createSimple( Basic.class.getName() ) )
);
memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar" );
memberAnnotations = JandexHelper.getMemberAnnotations( classInfo, "fubar", serviceRegistry );
assertTrue( "there should be no annotations in fubar", memberAnnotations.isEmpty() );
}