HHH-8533 - Add tests of JPA Metamodel handling for MappedSuperclass and mixed @Id/@IdClass declaration

This commit is contained in:
Steve Ebersole 2013-09-20 22:05:24 -05:00
parent 9360f4d9d4
commit 4d5174f55f
4 changed files with 37 additions and 20 deletions

View File

@ -945,12 +945,11 @@ public final class AnnotationBinder {
persistentClass.setIdentifierMapper( mapper ); persistentClass.setIdentifierMapper( mapper );
//If id definition is on a mapped superclass, update the mapping //If id definition is on a mapped superclass, update the mapping
final org.hibernate.mapping.MappedSuperclass superclass = final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
BinderHelper.getMappedSuperclassOrNull( classWithIdClass,
inferredData.getDeclaringClass(), inheritanceStatePerClass,
inheritanceStatePerClass, mappings
mappings );
);
if ( superclass != null ) { if ( superclass != null ) {
superclass.setDeclaredIdentifierMapper( mapper ); superclass.setDeclaredIdentifierMapper( mapper );
} }

View File

@ -31,6 +31,9 @@ import javax.persistence.metamodel.IdentifiableType;
import javax.persistence.metamodel.SingularAttribute; import javax.persistence.metamodel.SingularAttribute;
import javax.persistence.metamodel.Type; import javax.persistence.metamodel.Type;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.mapping.Component;
/** /**
* Defines commonality for the JPA {@link IdentifiableType} types. JPA defines * Defines commonality for the JPA {@link IdentifiableType} types. JPA defines
* identifiable types as entities or mapped-superclasses. Basically things to which an * identifiable types as entities or mapped-superclasses. Basically things to which an
@ -46,14 +49,14 @@ public abstract class AbstractIdentifiableType<X>
extends AbstractManagedType<X> extends AbstractManagedType<X>
implements IdentifiableType<X>, Serializable { implements IdentifiableType<X>, Serializable {
private final boolean hasIdClass;
private final boolean hasIdentifierProperty; private final boolean hasIdentifierProperty;
private final boolean isVersioned; private final boolean hasIdClass;
private SingularAttributeImpl<X, ?> id; private SingularAttributeImpl<X, ?> id;
private SingularAttributeImpl<X, ?> version;
private Set<SingularAttribute<? super X,?>> idClassAttributes; private Set<SingularAttribute<? super X,?>> idClassAttributes;
private final boolean isVersioned;
private SingularAttributeImpl<X, ?> version;
public AbstractIdentifiableType( public AbstractIdentifiableType(
Class<X> javaType, Class<X> javaType,
String typeName, String typeName,
@ -64,7 +67,7 @@ public abstract class AbstractIdentifiableType<X>
super( javaType, typeName, superType ); super( javaType, typeName, superType );
this.hasIdClass = hasIdClass; this.hasIdClass = hasIdClass;
this.hasIdentifierProperty = hasIdentifierProperty; this.hasIdentifierProperty = hasIdentifierProperty;
isVersioned = versioned; this.isVersioned = versioned;
} }
public boolean hasIdClass() { public boolean hasIdClass() {
@ -73,7 +76,7 @@ public abstract class AbstractIdentifiableType<X>
@Override @Override
public boolean hasSingleIdAttribute() { public boolean hasSingleIdAttribute() {
return !hasIdClass && hasIdentifierProperty; return !hasIdClass() && hasIdentifierProperty;
} }
@Override @Override
@ -95,7 +98,7 @@ public abstract class AbstractIdentifiableType<X>
} }
private void ensureNoIdClass() { private void ensureNoIdClass() {
if ( hasIdClass ) { if ( hasIdClass() ) {
throw new IllegalArgumentException( throw new IllegalArgumentException(
"Illegal call to IdentifiableType#getId for class [" + getTypeName() + "] defined with @IdClass" "Illegal call to IdentifiableType#getId for class [" + getTypeName() + "] defined with @IdClass"
); );
@ -158,9 +161,21 @@ public abstract class AbstractIdentifiableType<X>
} }
@Override @Override
@SuppressWarnings("unchecked")
public Type<?> getIdType() { public Type<?> getIdType() {
SingularAttributeImpl id = locateIdAttribute(); final SingularAttributeImpl id = locateIdAttribute();
return id == null ? null : id.getType(); if ( id != null ) {
return id.getType();
}
Set<SingularAttribute<? super X, ?>> idClassAttributes = getIdClassAttributesSafely();
if ( idClassAttributes != null ) {
if ( idClassAttributes.size() == 1 ) {
return idClassAttributes.iterator().next().getType();
}
}
return null;
} }
/** /**
@ -169,7 +184,7 @@ public abstract class AbstractIdentifiableType<X>
* @return IdClass attributes or {@code null} * @return IdClass attributes or {@code null}
*/ */
public Set<SingularAttribute<? super X, ?>> getIdClassAttributesSafely() { public Set<SingularAttribute<? super X, ?>> getIdClassAttributesSafely() {
if ( !hasIdClass ) { if ( !hasIdClass() ) {
return null; return null;
} }
final Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>(); final Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
@ -184,7 +199,7 @@ public abstract class AbstractIdentifiableType<X>
@Override @Override
public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() { public Set<SingularAttribute<? super X, ?>> getIdClassAttributes() {
if ( !hasIdClass ) { if ( !hasIdClass() ) {
throw new IllegalArgumentException( "This class [" + getJavaType() + "] does not define an IdClass" ); throw new IllegalArgumentException( "This class [" + getJavaType() + "] does not define an IdClass" );
} }

View File

@ -38,7 +38,7 @@ public class MappedSuperclassTypeImpl<X> extends AbstractIdentifiableType<X> imp
AbstractIdentifiableType<? super X> superType) { AbstractIdentifiableType<? super X> superType) {
super( super(
javaType, javaType,
null, javaType.getName(),
superType, superType,
mappedSuperclass.getDeclaredIdentifierMapper() != null || ( superType != null && superType.hasIdClass() ), mappedSuperclass.getDeclaredIdentifierMapper() != null || ( superType != null && superType.hasIdClass() ),
mappedSuperclass.hasIdentifierProperty(), mappedSuperclass.hasIdentifierProperty(),

View File

@ -39,6 +39,7 @@ import org.hibernate.testing.TestForIssue;
import static org.junit.Assert.assertEquals; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse; import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNotNull;
import static org.junit.Assert.fail; import static org.junit.Assert.fail;
/** /**
@ -64,10 +65,12 @@ public class MixedIdAndIdClassHandling extends BaseEntityManagerFunctionalTestCa
catch (IllegalArgumentException expected) { catch (IllegalArgumentException expected) {
} }
assertNotNull( entityType.getSupertype().getIdClassAttributes() );
assertEquals( 1, entityType.getSupertype().getIdClassAttributes().size() );
assertFalse( entityType.hasSingleIdAttribute() ); assertFalse( entityType.hasSingleIdAttribute() );
// this is questionable... assertEquals( String.class, entityType.getIdType().getJavaType() );
//assertEquals( String.class, entityType.getIdType().getJavaType() );
} }
@MappedSuperclass @MappedSuperclass