HHH-6172 Extracting initial attributes for ManyToOne
This commit is contained in:
parent
49e75c83ce
commit
3960b0d8ea
|
@ -22,18 +22,20 @@
|
|||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.annotations;
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
import java.lang.annotation.Retention;
|
||||
import java.lang.annotation.Target;
|
||||
|
||||
import static java.lang.annotation.ElementType.FIELD;
|
||||
import static java.lang.annotation.ElementType.METHOD;
|
||||
import static java.lang.annotation.RetentionPolicy.RUNTIME;
|
||||
|
||||
/**
|
||||
* Action to do when an element is not found on a association whiel beeing expected
|
||||
* Action to do when an element is not found on a association.
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Target({METHOD, FIELD})
|
||||
@Target( { METHOD, FIELD })
|
||||
@Retention(RUNTIME)
|
||||
public @interface NotFound {
|
||||
NotFoundAction action() default NotFoundAction.EXCEPTION;
|
||||
|
|
|
@ -27,13 +27,20 @@ import java.util.List;
|
|||
import java.util.Map;
|
||||
|
||||
import org.jboss.jandex.AnnotationInstance;
|
||||
import org.jboss.jandex.AnnotationValue;
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
import org.hibernate.annotations.NotFoundAction;
|
||||
import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class AssociationAttribute extends SimpleAttribute {
|
||||
private final AssociationType associationType;
|
||||
private final boolean ignoreNotFound;
|
||||
private final String referencedEntityType;
|
||||
|
||||
public static AssociationAttribute createAssociationAttribute(String name, String type, AssociationType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
return new AssociationAttribute( name, type, associationType, annotations );
|
||||
|
@ -42,11 +49,56 @@ public class AssociationAttribute extends SimpleAttribute {
|
|||
private AssociationAttribute(String name, String type, AssociationType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
super( name, type, annotations, false );
|
||||
this.associationType = associationType;
|
||||
this.ignoreNotFound = ignoreNotFound();
|
||||
|
||||
AnnotationInstance associationAnnotation = JandexHelper.getSingleAnnotation(
|
||||
annotations,
|
||||
associationType.getAnnotationDotName()
|
||||
);
|
||||
|
||||
referencedEntityType = determineReferencedEntityType( associationAnnotation );
|
||||
}
|
||||
|
||||
public boolean isIgnoreNotFound() {
|
||||
return ignoreNotFound;
|
||||
}
|
||||
|
||||
public String getReferencedEntityType() {
|
||||
return referencedEntityType;
|
||||
}
|
||||
|
||||
public AssociationType getAssociationType() {
|
||||
return associationType;
|
||||
}
|
||||
|
||||
private boolean ignoreNotFound() {
|
||||
NotFoundAction action = NotFoundAction.EXCEPTION;
|
||||
AnnotationInstance notFoundAnnotation = getIfExists( HibernateDotNames.NOT_FOUND );
|
||||
if ( notFoundAnnotation != null ) {
|
||||
AnnotationValue actionValue = notFoundAnnotation.value( "action" );
|
||||
if ( actionValue != null ) {
|
||||
action = Enum.valueOf( NotFoundAction.class, actionValue.asEnum() );
|
||||
}
|
||||
}
|
||||
|
||||
return NotFoundAction.IGNORE.equals( action );
|
||||
}
|
||||
|
||||
private String determineReferencedEntityType(AnnotationInstance associationAnnotation) {
|
||||
String targetTypeName = getType();
|
||||
|
||||
AnnotationInstance targetAnnotation = getIfExists( HibernateDotNames.TARGET );
|
||||
if ( targetAnnotation != null ) {
|
||||
targetTypeName = targetAnnotation.value().asClass().name().toString();
|
||||
}
|
||||
|
||||
AnnotationValue targetEntityValue = associationAnnotation.value( "targetEntity" );
|
||||
if ( targetEntityValue != null ) {
|
||||
targetTypeName = targetEntityValue.asClass().name().toString();
|
||||
}
|
||||
|
||||
return targetTypeName;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -23,13 +23,27 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.source.annotations.entity;
|
||||
|
||||
import org.jboss.jandex.DotName;
|
||||
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
|
||||
/**
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public enum AssociationType {
|
||||
NO_ASSOCIATION,
|
||||
ONE_TO_ONE,
|
||||
ONE_TO_MANY,
|
||||
MANY_TO_ONE,
|
||||
MANY_TO_MANY
|
||||
NO_ASSOCIATION( null ),
|
||||
ONE_TO_ONE( JPADotNames.ONE_TO_ONE ),
|
||||
ONE_TO_MANY( JPADotNames.ONE_TO_MANY ),
|
||||
MANY_TO_ONE( JPADotNames.MANY_TO_ONE ),
|
||||
MANY_TO_MANY( JPADotNames.MANY_TO_MANY );
|
||||
|
||||
private final DotName annotationDotName;
|
||||
|
||||
AssociationType(DotName annotationDotName) {
|
||||
this.annotationDotName = annotationDotName;
|
||||
}
|
||||
|
||||
public DotName getAnnotationDotName() {
|
||||
return annotationDotName;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -39,7 +39,9 @@ import org.hibernate.cache.spi.RegionFactory;
|
|||
import org.hibernate.cache.spi.access.AccessType;
|
||||
import org.hibernate.metamodel.binding.Caching;
|
||||
import org.hibernate.metamodel.binding.EntityBinding;
|
||||
import org.hibernate.metamodel.binding.ManyToOneAttributeBinding;
|
||||
import org.hibernate.metamodel.binding.SimpleAttributeBinding;
|
||||
import org.hibernate.metamodel.binding.state.ManyToOneAttributeBindingState;
|
||||
import org.hibernate.metamodel.binding.state.SimpleAttributeBindingState;
|
||||
import org.hibernate.metamodel.domain.Entity;
|
||||
import org.hibernate.metamodel.domain.Hierarchical;
|
||||
|
@ -49,7 +51,9 @@ import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
|||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.entity.state.binding.AttributeBindingStateImpl;
|
||||
import org.hibernate.metamodel.source.annotations.entity.state.binding.DiscriminatorBindingStateImpl;
|
||||
import org.hibernate.metamodel.source.annotations.entity.state.binding.ManyToOneBindingStateImpl;
|
||||
import org.hibernate.metamodel.source.annotations.entity.state.relational.ColumnRelationalStateImpl;
|
||||
import org.hibernate.metamodel.source.annotations.entity.state.relational.ManyToOneRelationalStateImpl;
|
||||
import org.hibernate.metamodel.source.annotations.entity.state.relational.TupleRelationalStateImpl;
|
||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.source.spi.MetadataImplementor;
|
||||
|
@ -319,7 +323,7 @@ public class EntityBinder {
|
|||
private void bindAttributes(EntityBinding entityBinding) {
|
||||
for ( MappedAttribute mappedAttribute : configuredClass.getMappedAttributes() ) {
|
||||
if ( mappedAttribute instanceof AssociationAttribute ) {
|
||||
// todo
|
||||
bindAssociationAttribute( entityBinding, (AssociationAttribute) mappedAttribute );
|
||||
}
|
||||
else {
|
||||
bindSingleMappedAttribute( entityBinding, (SimpleAttribute) mappedAttribute );
|
||||
|
@ -327,39 +331,64 @@ public class EntityBinder {
|
|||
}
|
||||
}
|
||||
|
||||
private void bindSingleMappedAttribute(EntityBinding entityBinding, SimpleAttribute mappedAttribute) {
|
||||
if ( mappedAttribute.isId() ) {
|
||||
private void bindAssociationAttribute(EntityBinding entityBinding, AssociationAttribute associationAttribute) {
|
||||
switch ( associationAttribute.getAssociationType() ) {
|
||||
case MANY_TO_ONE: {
|
||||
entityBinding.getEntity().getOrCreateSingularAttribute( associationAttribute.getName() );
|
||||
ManyToOneAttributeBinding manyToOneAttributeBinding = entityBinding.makeManyToOneAttributeBinding(
|
||||
associationAttribute.getName()
|
||||
);
|
||||
|
||||
ManyToOneAttributeBindingState bindingState = new ManyToOneBindingStateImpl( associationAttribute );
|
||||
manyToOneAttributeBinding.initialize( bindingState );
|
||||
|
||||
ManyToOneRelationalStateImpl relationalState = new ManyToOneRelationalStateImpl();
|
||||
if ( configuredClass.hasOwnTable() ) {
|
||||
ColumnRelationalStateImpl columnRelationsState = new ColumnRelationalStateImpl(
|
||||
associationAttribute, meta
|
||||
);
|
||||
relationalState.addValueState( columnRelationsState );
|
||||
}
|
||||
manyToOneAttributeBinding.initialize( relationalState );
|
||||
break;
|
||||
}
|
||||
default: {
|
||||
// todo
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void bindSingleMappedAttribute(EntityBinding entityBinding, SimpleAttribute simpleAttribute) {
|
||||
if ( simpleAttribute.isId() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
String attributeName = mappedAttribute.getName();
|
||||
String attributeName = simpleAttribute.getName();
|
||||
entityBinding.getEntity().getOrCreateSingularAttribute( attributeName );
|
||||
SimpleAttributeBinding attributeBinding;
|
||||
SimpleAttributeBindingState bindingState;
|
||||
|
||||
if ( mappedAttribute.isDiscriminator() ) {
|
||||
if ( simpleAttribute.isDiscriminator() ) {
|
||||
attributeBinding = entityBinding.makeEntityDiscriminator( attributeName ).getValueBinding();
|
||||
bindingState = new DiscriminatorBindingStateImpl( mappedAttribute );
|
||||
bindingState = new DiscriminatorBindingStateImpl( simpleAttribute );
|
||||
}
|
||||
else if ( mappedAttribute.isVersioned() ) {
|
||||
else if ( simpleAttribute.isVersioned() ) {
|
||||
attributeBinding = entityBinding.makeVersionBinding( attributeName );
|
||||
bindingState = new AttributeBindingStateImpl( mappedAttribute );
|
||||
bindingState = new AttributeBindingStateImpl( simpleAttribute );
|
||||
}
|
||||
else {
|
||||
attributeBinding = entityBinding.makeSimpleAttributeBinding( attributeName );
|
||||
bindingState = new AttributeBindingStateImpl( mappedAttribute );
|
||||
bindingState = new AttributeBindingStateImpl( simpleAttribute );
|
||||
}
|
||||
attributeBinding.initialize( bindingState );
|
||||
|
||||
if ( configuredClass.hasOwnTable() ) {
|
||||
ColumnRelationalStateImpl columnRelationsState = new ColumnRelationalStateImpl(
|
||||
mappedAttribute, meta
|
||||
simpleAttribute, meta
|
||||
);
|
||||
TupleRelationalStateImpl relationalState = new TupleRelationalStateImpl();
|
||||
relationalState.addValueState( columnRelationsState );
|
||||
|
||||
// TODO: if this really just binds a column, then it can be changed to
|
||||
// attributeBinding.initialize( columnRelationsState );
|
||||
attributeBinding.initialize( relationalState );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -46,9 +46,9 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
private final Map<DotName, List<AnnotationInstance>> annotations;
|
||||
|
||||
/**
|
||||
* The property type as string.
|
||||
* The property name.
|
||||
*/
|
||||
private final String type;
|
||||
private final String name;
|
||||
|
||||
/**
|
||||
* Optional type parameters for custom types.
|
||||
|
@ -56,9 +56,9 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
private final Map<String, String> typeParameters;
|
||||
|
||||
/**
|
||||
* The property name.
|
||||
* The property type as string.
|
||||
*/
|
||||
private final String name;
|
||||
private final String type;
|
||||
|
||||
MappedAttribute(String name, String type, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
this.annotations = annotations;
|
||||
|
@ -101,6 +101,22 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MappedAttribute mappedProperty) {
|
||||
return name.compareTo( mappedProperty.getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "MappedAttribute" );
|
||||
sb.append( "{type='" ).append( type ).append( '\'' );
|
||||
sb.append( ", typeParameters=" ).append( typeParameters );
|
||||
sb.append( ", name='" ).append( name ).append( '\'' );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
|
||||
/**
|
||||
* We need to check whether the is an explicit type specified via {@link org.hibernate.annotations.Type}.
|
||||
*
|
||||
|
@ -129,22 +145,6 @@ public class MappedAttribute implements Comparable<MappedAttribute> {
|
|||
|
||||
return typeAnnotation.value( "type" ).asString();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int compareTo(MappedAttribute mappedProperty) {
|
||||
return name.compareTo( mappedProperty.getName() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
final StringBuilder sb = new StringBuilder();
|
||||
sb.append( "MappedAttribute" );
|
||||
sb.append( "{type='" ).append( type ).append( '\'' );
|
||||
sb.append( ", typeParameters=" ).append( typeParameters );
|
||||
sb.append( ", name='" ).append( name ).append( '\'' );
|
||||
sb.append( '}' );
|
||||
return sb.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -30,28 +30,41 @@ import org.hibernate.metamodel.source.annotations.entity.AssociationAttribute;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class ManyToOneBindingStateImpl extends AttributeBindingStateImpl implements ManyToOneAttributeBindingState {
|
||||
private final AssociationAttribute associationAttribute;
|
||||
|
||||
public ManyToOneBindingStateImpl(AssociationAttribute associationAttribute) {
|
||||
super( associationAttribute );
|
||||
this.associationAttribute = associationAttribute;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnwrapProxy() {
|
||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||
public boolean isLazy() {
|
||||
return associationAttribute.isLazy();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
public String getCascade() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedEntityName() {
|
||||
return null; //To change body of implemented methods use File | Settings | File Templates.
|
||||
return associationAttribute.getReferencedEntityType();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean ignoreNotFound() {
|
||||
return false; //To change body of implemented methods use File | Settings | File Templates.
|
||||
return associationAttribute.isIgnoreNotFound();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isUnwrapProxy() {
|
||||
return false;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getReferencedAttributeName() {
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -23,11 +23,8 @@
|
|||
*/
|
||||
package org.hibernate.metamodel.binding;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.metamodel.MetadataSources;
|
||||
import org.hibernate.metamodel.source.internal.MetadataImpl;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
|
||||
/**
|
||||
* Basic tests of annotation based binding code
|
||||
|
@ -35,16 +32,9 @@ import org.hibernate.testing.FailureExpected;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class BasicAnnotationBindingTests extends AbstractBasicBindingTests {
|
||||
@FailureExpected(jiraKey = "HHH-6172", message = "Work in progress")
|
||||
@Test
|
||||
public void testEntityWithManyToOneMapping() {
|
||||
super.testEntityWithManyToOneMapping();
|
||||
}
|
||||
|
||||
public MetadataImpl addSourcesForSimpleEntityBinding(MetadataSources sources) {
|
||||
sources.addAnnotatedClass( SimpleEntity.class );
|
||||
return (MetadataImpl) sources.buildMetadata();
|
||||
|
||||
}
|
||||
|
||||
public MetadataImpl addSourcesForSimpleVersionedEntityBinding(MetadataSources sources) {
|
||||
|
|
Loading…
Reference in New Issue