HHH-4533 Populate the JPA 2 metamodel with the new mapping.MappedSuperclass metadata
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17879 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
fceda002d0
commit
fb9bdb7f38
|
@ -775,6 +775,21 @@ public final class AnnotationBinder {
|
|||
);
|
||||
entityBinder.setIgnoreIdAnnotations( ignoreIdAnnotations );
|
||||
persistentClass.setIdentifierMapper( mapper );
|
||||
|
||||
//If id definition is on a mapped superclass, update the mapping
|
||||
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
|
||||
inferredData.getDeclaringClass(),
|
||||
inheritanceStatePerClass,
|
||||
mappings
|
||||
);
|
||||
if (superclass != null) {
|
||||
superclass.setDeclaredIdentifierMapper(mapper);
|
||||
}
|
||||
else {
|
||||
//we are for sure on the entity
|
||||
persistentClass.setDeclaredIdentifierMapper( mapper );
|
||||
}
|
||||
|
||||
Property property = new Property();
|
||||
property.setName( "_identifierMapper" );
|
||||
property.setNodeName( "id" );
|
||||
|
@ -1462,6 +1477,20 @@ public final class AnnotationBinder {
|
|||
Property prop = propBinder.bind();
|
||||
propBinder.getSimpleValueBinder().setVersion(true);
|
||||
rootClass.setVersion( prop );
|
||||
|
||||
//If version is on a mapped superclass, update the mapping
|
||||
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
|
||||
inferredData.getDeclaringClass(),
|
||||
inheritanceStatePerClass,
|
||||
mappings
|
||||
);
|
||||
if (superclass != null) {
|
||||
superclass.setDeclaredVersion(prop);
|
||||
}
|
||||
else {
|
||||
//we know the property is on the actual entity
|
||||
rootClass.setDeclaredVersion( prop );
|
||||
}
|
||||
|
||||
SimpleValue simpleValue = (SimpleValue) prop.getValue();
|
||||
simpleValue.setNullValue( "undefined" );
|
||||
|
@ -2202,6 +2231,19 @@ public final class AnnotationBinder {
|
|||
binder.setProperty( inferredData.getProperty() );
|
||||
Property prop = binder.make();
|
||||
rootClass.setIdentifierProperty( prop );
|
||||
//if the id property is on a superclass, update the metamodel
|
||||
final org.hibernate.mapping.MappedSuperclass superclass = BinderHelper.getMappedSuperclassOrNull(
|
||||
inferredData.getDeclaringClass(),
|
||||
inheritanceStatePerClass,
|
||||
mappings
|
||||
);
|
||||
if (superclass != null) {
|
||||
superclass.setDeclaredIdentifierProperty(prop);
|
||||
}
|
||||
else {
|
||||
//we know the property is on the actual entity
|
||||
rootClass.setDeclaredIdentifierProperty( prop );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -60,6 +60,7 @@ import org.hibernate.mapping.SimpleValue;
|
|||
import org.hibernate.mapping.Table;
|
||||
import org.hibernate.mapping.ToOne;
|
||||
import org.hibernate.mapping.Value;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.type.TypeFactory;
|
||||
import org.hibernate.util.StringHelper;
|
||||
import org.slf4j.Logger;
|
||||
|
@ -575,4 +576,24 @@ public class BinderHelper {
|
|||
log.info( "Binding Any Meta definition: {}", defAnn.name() );
|
||||
mappings.addAnyMetaDef( defAnn );
|
||||
}
|
||||
|
||||
public static MappedSuperclass getMappedSuperclassOrNull(XClass declaringClass,
|
||||
Map<XClass, InheritanceState> inheritanceStatePerClass,
|
||||
ExtendedMappings mappings) {
|
||||
boolean retrieve = false;
|
||||
if ( declaringClass != null ) {
|
||||
final InheritanceState inheritanceState = inheritanceStatePerClass.get( declaringClass );
|
||||
if ( inheritanceState == null ) {
|
||||
throw new org.hibernate.annotations.common.AssertionFailure(
|
||||
"Declaring class is not found in the inheritance state hierarchy: " + declaringClass
|
||||
);
|
||||
}
|
||||
if ( inheritanceState.isEmbeddableSuperclass ) {
|
||||
retrieve = true;
|
||||
}
|
||||
}
|
||||
return retrieve ?
|
||||
mappings.getMappedSuperclass( mappings.getReflectionManager().toClass( declaringClass ) ) :
|
||||
null;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -130,7 +130,7 @@ public class ClassPropertyHolder extends AbstractPropertyHolder {
|
|||
final ExtendedMappings mappings = getMappings();
|
||||
final Class type = mappings.getReflectionManager().toClass( declaringClass );
|
||||
MappedSuperclass superclass = mappings.getMappedSuperclass( type );
|
||||
superclass.addProperty( prop );
|
||||
superclass.addDeclaredProperty( prop );
|
||||
}
|
||||
|
||||
private void addPropertyToJoin(Property prop, XClass declaringClass, Join join) {
|
||||
|
|
|
@ -12,20 +12,27 @@ import java.util.List;
|
|||
*
|
||||
* Do not use outside this use case.
|
||||
*
|
||||
* A proper redesign will be evluated in Hibernate 4
|
||||
*
|
||||
* A proper redesign will be evaluated in Hibernate 4
|
||||
*
|
||||
* Implementation details:
|
||||
* properties are copies of their closest sub-persistentClass versions
|
||||
*
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class MappedSuperclass {
|
||||
private final MappedSuperclass superMappedSuperclass;
|
||||
private final PersistentClass superPersistentClass;
|
||||
private final List properties;
|
||||
private final List declaredProperties;
|
||||
private Class mappedClass;
|
||||
private Property identifierProperty;
|
||||
private Property version;
|
||||
private Component identifierMapper;
|
||||
|
||||
public MappedSuperclass(MappedSuperclass superMappedSuperclass, PersistentClass superPersistentClass) {
|
||||
this.superMappedSuperclass = superMappedSuperclass;
|
||||
this.superPersistentClass = superPersistentClass;
|
||||
this.properties = new ArrayList();
|
||||
this.declaredProperties = new ArrayList();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -39,6 +46,14 @@ public class MappedSuperclass {
|
|||
return superMappedSuperclass;
|
||||
}
|
||||
|
||||
public boolean hasIdentifierProperty() {
|
||||
return getIdentifierProperty() != null;
|
||||
}
|
||||
|
||||
public boolean isVersioned() {
|
||||
return getVersion() != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the PersistentClass of the first superclass marked as @Entity
|
||||
* or null if none exists
|
||||
|
@ -49,21 +64,21 @@ public class MappedSuperclass {
|
|||
return superPersistentClass;
|
||||
}
|
||||
|
||||
public Iterator getPropertyIterator() {
|
||||
return properties.iterator();
|
||||
public Iterator getDeclaredPropertyIterator() {
|
||||
return declaredProperties.iterator();
|
||||
}
|
||||
|
||||
public void addProperty(Property p) {
|
||||
public void addDeclaredProperty(Property p) {
|
||||
//Do not add duplicate properties
|
||||
//TODO is it efficient enough?
|
||||
String name = p.getName();
|
||||
Iterator it = properties.iterator();
|
||||
Iterator it = declaredProperties.iterator();
|
||||
while (it.hasNext()) {
|
||||
if ( name.equals( ((Property)it.next()).getName() ) ) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
properties.add(p);
|
||||
declaredProperties.add(p);
|
||||
}
|
||||
|
||||
public Class getMappedClass() {
|
||||
|
@ -73,4 +88,73 @@ public class MappedSuperclass {
|
|||
public void setMappedClass(Class mappedClass) {
|
||||
this.mappedClass = mappedClass;
|
||||
}
|
||||
|
||||
public Property getIdentifierProperty() {
|
||||
//get direct identifiermapper or the one from the super mappedSuperclass
|
||||
// or the one from the super persistentClass
|
||||
Property propagatedIdentifierProp = identifierProperty;
|
||||
if ( propagatedIdentifierProp == null ) {
|
||||
if ( superMappedSuperclass != null ) {
|
||||
propagatedIdentifierProp = superMappedSuperclass.getIdentifierProperty();
|
||||
}
|
||||
if (propagatedIdentifierProp == null && superPersistentClass != null){
|
||||
propagatedIdentifierProp = superPersistentClass.getIdentifierProperty();
|
||||
}
|
||||
}
|
||||
return propagatedIdentifierProp;
|
||||
}
|
||||
|
||||
public Property getDeclaredIdentifierProperty() {
|
||||
return identifierProperty;
|
||||
}
|
||||
|
||||
public void setDeclaredIdentifierProperty(Property prop) {
|
||||
this.identifierProperty = prop;
|
||||
}
|
||||
|
||||
public Property getVersion() {
|
||||
//get direct version or the one from the super mappedSuperclass
|
||||
// or the one from the super persistentClass
|
||||
Property propagatedVersion = version;
|
||||
if (propagatedVersion == null) {
|
||||
if ( superMappedSuperclass != null ) {
|
||||
propagatedVersion = superMappedSuperclass.getVersion();
|
||||
}
|
||||
if (propagatedVersion == null && superPersistentClass != null){
|
||||
propagatedVersion = superPersistentClass.getVersion();
|
||||
}
|
||||
}
|
||||
return propagatedVersion;
|
||||
}
|
||||
|
||||
public Property getDeclaredVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setDeclaredVersion(Property prop) {
|
||||
this.version = prop;
|
||||
}
|
||||
|
||||
public Component getIdentifierMapper() {
|
||||
//get direct identifiermapper or the one from the super mappedSuperclass
|
||||
// or the one from the super persistentClass
|
||||
Component propagatedMapper = identifierMapper;
|
||||
if ( propagatedMapper == null ) {
|
||||
if ( superMappedSuperclass != null ) {
|
||||
propagatedMapper = superMappedSuperclass.getIdentifierMapper();
|
||||
}
|
||||
if (propagatedMapper == null && superPersistentClass != null){
|
||||
propagatedMapper = superPersistentClass.getIdentifierMapper();
|
||||
}
|
||||
}
|
||||
return propagatedMapper;
|
||||
}
|
||||
|
||||
public Component getDeclaredIdentifierMapper() {
|
||||
return identifierMapper;
|
||||
}
|
||||
|
||||
public void setDeclaredIdentifierMapper(Component identifierMapper) {
|
||||
this.identifierMapper = identifierMapper;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -98,6 +98,7 @@ public abstract class PersistentClass implements Serializable, Filterable, MetaA
|
|||
|
||||
protected int optimisticLockMode;
|
||||
private MappedSuperclass superMappedSuperclass;
|
||||
private Component declaredIdentifierMapper;
|
||||
|
||||
public String getClassName() {
|
||||
return className;
|
||||
|
@ -236,8 +237,10 @@ public abstract class PersistentClass implements Serializable, Filterable, MetaA
|
|||
public abstract boolean isMutable();
|
||||
public abstract boolean hasIdentifierProperty();
|
||||
public abstract Property getIdentifierProperty();
|
||||
public abstract Property getDeclaredIdentifierProperty();
|
||||
public abstract KeyValue getIdentifier();
|
||||
public abstract Property getVersion();
|
||||
public abstract Property getDeclaredVersion();
|
||||
public abstract Value getDiscriminator();
|
||||
public abstract boolean isInherited();
|
||||
public abstract boolean isPolymorphic();
|
||||
|
@ -776,6 +779,14 @@ public abstract class PersistentClass implements Serializable, Filterable, MetaA
|
|||
return identifierMapper;
|
||||
}
|
||||
|
||||
public Component getDeclaredIdentifierMapper() {
|
||||
return declaredIdentifierMapper;
|
||||
}
|
||||
|
||||
public void setDeclaredIdentifierMapper(Component declaredIdentifierMapper) {
|
||||
this.declaredIdentifierMapper = declaredIdentifierMapper;
|
||||
}
|
||||
|
||||
public boolean hasIdentifierMapper() {
|
||||
return identifierMapper != null;
|
||||
}
|
||||
|
|
|
@ -61,7 +61,9 @@ public class RootClass extends PersistentClass implements TableOwner {
|
|||
private Table table;
|
||||
private boolean discriminatorInsertable = true;
|
||||
private int nextSubclassId = 0;
|
||||
|
||||
private Property declaredIdentifierProperty;
|
||||
private Property declaredVersion;
|
||||
|
||||
int nextSubclassId() {
|
||||
return ++nextSubclassId;
|
||||
}
|
||||
|
@ -80,6 +82,15 @@ public class RootClass extends PersistentClass implements TableOwner {
|
|||
public Property getIdentifierProperty() {
|
||||
return identifierProperty;
|
||||
}
|
||||
|
||||
public Property getDeclaredIdentifierProperty() {
|
||||
return declaredIdentifierProperty;
|
||||
}
|
||||
|
||||
public void setDeclaredIdentifierProperty(Property declaredIdentifierProperty) {
|
||||
this.declaredIdentifierProperty = declaredIdentifierProperty;
|
||||
}
|
||||
|
||||
public KeyValue getIdentifier() {
|
||||
return identifier;
|
||||
}
|
||||
|
@ -128,6 +139,15 @@ public class RootClass extends PersistentClass implements TableOwner {
|
|||
public Property getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public Property getDeclaredVersion() {
|
||||
return declaredVersion;
|
||||
}
|
||||
|
||||
public void setDeclaredVersion(Property declaredVersion) {
|
||||
this.declaredVersion = declaredVersion;
|
||||
}
|
||||
|
||||
public void setVersion(Property version) {
|
||||
this.version = version;
|
||||
}
|
||||
|
@ -181,6 +201,7 @@ public class RootClass extends PersistentClass implements TableOwner {
|
|||
public void setIdentifierProperty(Property identifierProperty) {
|
||||
this.identifierProperty = identifierProperty;
|
||||
identifierProperty.setPersistentClass(this);
|
||||
|
||||
}
|
||||
|
||||
public void setMutable(boolean mutable) {
|
||||
|
|
|
@ -70,6 +70,11 @@ public class Subclass extends PersistentClass {
|
|||
public Property getIdentifierProperty() {
|
||||
return getSuperclass().getIdentifierProperty();
|
||||
}
|
||||
|
||||
public Property getDeclaredIdentifierProperty() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public KeyValue getIdentifier() {
|
||||
return getSuperclass().getIdentifier();
|
||||
}
|
||||
|
@ -143,6 +148,10 @@ public class Subclass extends PersistentClass {
|
|||
return getSuperclass().getVersion();
|
||||
}
|
||||
|
||||
public Property getDeclaredVersion() {
|
||||
return null;
|
||||
}
|
||||
|
||||
public boolean hasEmbeddedIdentifier() {
|
||||
return getSuperclass().hasEmbeddedIdentifier();
|
||||
}
|
||||
|
|
|
@ -97,7 +97,19 @@ public abstract class AbstractIdentifiableType<X>
|
|||
}
|
||||
}
|
||||
else {
|
||||
id_ = requireSupertype().getId( javaType );
|
||||
//yuk yuk bad me
|
||||
if (this instanceof MappedSuperclassTypeImpl) {
|
||||
final AbstractIdentifiableType<? super X> supertype = getSupertype();
|
||||
if (supertype != null) {
|
||||
id_ = supertype.getId( javaType );
|
||||
}
|
||||
else {
|
||||
id_ = null;
|
||||
}
|
||||
}
|
||||
else {
|
||||
id_ = requireSupertype().getId( javaType );
|
||||
}
|
||||
}
|
||||
return id_;
|
||||
}
|
||||
|
@ -227,6 +239,7 @@ public abstract class AbstractIdentifiableType<X>
|
|||
return new Builder<X>() {
|
||||
public void applyIdAttribute(SingularAttributeImpl<X, ?> idAttribute) {
|
||||
AbstractIdentifiableType.this.id = idAttribute;
|
||||
managedBuilder.addAttribute( idAttribute );
|
||||
}
|
||||
|
||||
public void applyIdClassAttributes(Set<SingularAttribute<? super X,?>> idClassAttributes) {
|
||||
|
|
|
@ -54,19 +54,19 @@ public class AttributeFactory {
|
|||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <X, Y> AttributeImplementor<X, Y> buildAttribute(AbstractManagedType<X> ownerType, Property property) {
|
||||
public <X, Y> AttributeImplementor<X, Y> buildAttribute(AbstractManagedType<X> ownerType, Property property, boolean getMember) {
|
||||
AttributeContext attrContext = getAttributeContext( property );
|
||||
final AttributeImplementor<X, Y> attribute;
|
||||
if ( attrContext.isCollection() ) {
|
||||
attribute = buildPluralAttribute( ownerType, property, attrContext );
|
||||
attribute = buildPluralAttribute( ownerType, property, attrContext, getMember );
|
||||
}
|
||||
else {
|
||||
final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() );
|
||||
final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue(), getMember );
|
||||
attribute = new SingularAttributeImpl<X,Y>(
|
||||
property.getName(),
|
||||
property.getType().getReturnedClass(),
|
||||
ownerType,
|
||||
determineStandardJavaMember( ownerType, property ),
|
||||
getMember ? determineStandardJavaMember( ownerType, property ) : null,
|
||||
false,
|
||||
false,
|
||||
property.isOptional(),
|
||||
|
@ -78,21 +78,21 @@ public class AttributeFactory {
|
|||
}
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private <X, Y, V, K> AttributeImplementor<X, Y> buildPluralAttribute(AbstractManagedType<X> ownerType, Property property, AttributeContext attrContext) {
|
||||
private <X, Y, V, K> AttributeImplementor<X, Y> buildPluralAttribute(AbstractManagedType<X> ownerType, Property property, AttributeContext attrContext, boolean getMember) {
|
||||
AttributeImplementor<X, Y> attribute;
|
||||
final Type<V> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() );
|
||||
final Type<V> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue(), getMember );
|
||||
final Class<Y> collectionClass = (Class<Y>) attrContext.getCollectionClass();
|
||||
if ( java.util.Map.class.isAssignableFrom( collectionClass ) ) {
|
||||
final Type<K> keyType = getType( ownerType, attrContext.getKeyTypeStatus(), attrContext.getKeyValue() );
|
||||
final Type<K> keyType = getType( ownerType, attrContext.getKeyTypeStatus(), attrContext.getKeyValue(), getMember );
|
||||
attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, keyType )
|
||||
.member( determineStandardJavaMember( ownerType, property ) )
|
||||
.member( getMember ? determineStandardJavaMember( ownerType, property ) : null )
|
||||
.property( property )
|
||||
.persistentAttributeType( attrContext.getElementAttributeType() )
|
||||
.build();
|
||||
}
|
||||
else {
|
||||
attribute = PluralAttributeImpl.create( ownerType, attrType, collectionClass, null )
|
||||
.member( determineStandardJavaMember( ownerType, property ) )
|
||||
.member( getMember ? determineStandardJavaMember( ownerType, property ) : null )
|
||||
.property( property )
|
||||
.persistentAttributeType( attrContext.getElementAttributeType() )
|
||||
.build();
|
||||
|
@ -100,13 +100,13 @@ public class AttributeFactory {
|
|||
return attribute;
|
||||
}
|
||||
|
||||
private <X> Type<X> getType(AbstractManagedType owner, AttributeContext.TypeStatus elementTypeStatus, Value value) {
|
||||
private <X> Type<X> getType(AbstractManagedType owner, AttributeContext.TypeStatus elementTypeStatus, Value value, boolean getMember) {
|
||||
final org.hibernate.type.Type type = value.getType();
|
||||
switch ( elementTypeStatus ) {
|
||||
case BASIC:
|
||||
return buildBasicType( type );
|
||||
case EMBEDDABLE:
|
||||
return buildEmbeddableType( owner, value, type );
|
||||
return buildEmbeddableType( owner, value, type, getMember );
|
||||
case ENTITY:
|
||||
return buildEntityType( type );
|
||||
default:
|
||||
|
@ -128,7 +128,7 @@ public class AttributeFactory {
|
|||
}
|
||||
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private <X> Type<X> buildEmbeddableType(AbstractManagedType owner, Value value, org.hibernate.type.Type type) {
|
||||
private <X> Type<X> buildEmbeddableType(AbstractManagedType owner, Value value, org.hibernate.type.Type type, boolean getMember) {
|
||||
//build embedable type
|
||||
final Class<X> clazz = type.getReturnedClass();
|
||||
final EmbeddableTypeImpl<X> embeddableType = new EmbeddableTypeImpl<X>( clazz, owner, (ComponentType) type );
|
||||
|
@ -137,22 +137,22 @@ public class AttributeFactory {
|
|||
final Iterator<Property> subProperties = component.getPropertyIterator();
|
||||
while ( subProperties.hasNext() ) {
|
||||
final Property property = subProperties.next();
|
||||
embeddableType.getBuilder().addAttribute( buildAttribute( embeddableType, property ) );
|
||||
embeddableType.getBuilder().addAttribute( buildAttribute( embeddableType, property, getMember ) );
|
||||
}
|
||||
embeddableType.lock();
|
||||
return embeddableType;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <X, Y> SingularAttributeImpl<X, Y> buildIdAttribute(AbstractManagedType<X> ownerType, Property property) {
|
||||
public <X, Y> SingularAttributeImpl<X, Y> buildIdAttribute(AbstractManagedType<X> ownerType, Property property, boolean getMember) {
|
||||
final AttributeContext attrContext = getAttributeContext( property );
|
||||
final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() );
|
||||
final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue(), getMember );
|
||||
final Class<Y> idJavaType = property.getType().getReturnedClass();
|
||||
return new SingularAttributeImpl.Identifier(
|
||||
property.getName(),
|
||||
idJavaType,
|
||||
ownerType,
|
||||
determineIdentifierJavaMember( ownerType, property ),
|
||||
getMember ? determineIdentifierJavaMember( ownerType, property ) : null,
|
||||
attrType,
|
||||
attrContext.getElementAttributeType()
|
||||
);
|
||||
|
@ -232,15 +232,15 @@ public class AttributeFactory {
|
|||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public <X, Y> SingularAttributeImpl<X, Y> buildVerisonAttribute(AbstractManagedType<X> ownerType, Property property) {
|
||||
public <X, Y> SingularAttributeImpl<X, Y> buildVersionAttribute(AbstractManagedType<X> ownerType, Property property, boolean getMember) {
|
||||
final AttributeContext attrContext = getAttributeContext( property );
|
||||
final Class<Y> javaType = property.getType().getReturnedClass();
|
||||
final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue() );
|
||||
final Type<Y> attrType = getType( ownerType, attrContext.getElementTypeStatus(), attrContext.getElementValue(), getMember );
|
||||
return new SingularAttributeImpl.Version(
|
||||
property.getName(),
|
||||
javaType,
|
||||
ownerType,
|
||||
determineVersionJavaMember( ownerType, property ),
|
||||
getMember ? determineVersionJavaMember( ownerType, property ) : null,
|
||||
attrType,
|
||||
attrContext.getElementAttributeType()
|
||||
);
|
||||
|
@ -252,7 +252,7 @@ public class AttributeFactory {
|
|||
// this should never happen, but to be safe...
|
||||
throw new IllegalArgumentException( "Given property did not match declared version property" );
|
||||
}
|
||||
return entityMetamodel.getTuplizer( EntityMode.POJO ).getIdentifierGetter().getMember();
|
||||
return entityMetamodel.getTuplizer( EntityMode.POJO ).getVersionGetter().getMember();
|
||||
}
|
||||
|
||||
private static class AttributeContext {
|
||||
|
|
|
@ -0,0 +1,21 @@
|
|||
package org.hibernate.ejb.metamodel;
|
||||
|
||||
import javax.persistence.metamodel.MappedSuperclassType;
|
||||
import javax.persistence.metamodel.Type;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
public class MappedSuperclassTypeImpl<X> extends AbstractIdentifiableType<X> implements MappedSuperclassType<X> {
|
||||
public MappedSuperclassTypeImpl(
|
||||
Class<X> javaType,
|
||||
AbstractIdentifiableType<? super X> superType,
|
||||
boolean hasIdentifierProperty,
|
||||
boolean versioned) {
|
||||
super( javaType, superType, hasIdentifierProperty, versioned );
|
||||
}
|
||||
|
||||
public PersistenceType getPersistenceType() {
|
||||
return PersistenceType.MAPPED_SUPERCLASS;
|
||||
}
|
||||
}
|
|
@ -25,16 +25,18 @@ import java.util.Collections;
|
|||
import java.util.HashMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.Iterator;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.annotations.common.AssertionFailure;
|
||||
|
||||
/**
|
||||
* Defines a context for storing information during the building of the {@link MetamodelImpl}.
|
||||
|
@ -53,14 +55,18 @@ class MetadataContext {
|
|||
private final SessionFactoryImplementor sessionFactory;
|
||||
private final AttributeFactory attributeFactory = new AttributeFactory( this );
|
||||
|
||||
private HashMap<Class<?>,EntityTypeImpl<?>> entityTypes
|
||||
private Map<Class<?>,EntityTypeImpl<?>> entityTypes
|
||||
= new HashMap<Class<?>, EntityTypeImpl<?>>();
|
||||
private HashMap<String,EntityTypeImpl<?>> entityTypesByEntityName
|
||||
private Map<String,EntityTypeImpl<?>> entityTypesByEntityName
|
||||
= new HashMap<String, EntityTypeImpl<?>>();
|
||||
private LinkedHashMap<PersistentClass,EntityTypeImpl<?>> entityTypesByPersistentClass
|
||||
= new LinkedHashMap<PersistentClass,EntityTypeImpl<?>>();
|
||||
private HashMap<Class<?>, EmbeddableTypeImpl<?>> embeddables
|
||||
private Map<PersistentClass,EntityTypeImpl<?>> entityTypesByPersistentClass
|
||||
= new HashMap<PersistentClass,EntityTypeImpl<?>>();
|
||||
private Map<Class<?>, EmbeddableTypeImpl<?>> embeddables
|
||||
= new HashMap<Class<?>, EmbeddableTypeImpl<?>>();
|
||||
private Map<MappedSuperclass, MappedSuperclassTypeImpl<?>> mappedSuperclassByMappedSuperclassMapping
|
||||
= new HashMap<MappedSuperclass,MappedSuperclassTypeImpl<?>>();
|
||||
//this list contains MappedSuperclass and EntityTypes ordered by superclass first
|
||||
private List<Object> orderedMappings = new ArrayList<Object>();
|
||||
|
||||
public MetadataContext(SessionFactoryImplementor sessionFactory) {
|
||||
this.sessionFactory = sessionFactory;
|
||||
|
@ -87,12 +93,19 @@ class MetadataContext {
|
|||
entityTypes.put( entityType.getBindableJavaType(), entityType );
|
||||
entityTypesByEntityName.put( persistentClass.getEntityName(), entityType );
|
||||
entityTypesByPersistentClass.put( persistentClass, entityType );
|
||||
orderedMappings.add( persistentClass );
|
||||
}
|
||||
|
||||
/*package*/ void registerEmbeddedableType(EmbeddableTypeImpl<?> embeddableType) {
|
||||
embeddables.put( embeddableType.getJavaType(), embeddableType );
|
||||
}
|
||||
|
||||
/*package*/ void registerMappedSuperclassType(MappedSuperclass mappedSuperclass,
|
||||
MappedSuperclassTypeImpl<?> mappedSuperclassType) {
|
||||
mappedSuperclassByMappedSuperclassMapping.put( mappedSuperclass, mappedSuperclassType );
|
||||
orderedMappings.add( mappedSuperclass );
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a Hibernate {@link PersistentClass}, locate the corresponding JPA {@link org.hibernate.type.EntityType}
|
||||
* implementation. May retur null if the given {@link PersistentClass} has not yet been processed.
|
||||
|
@ -128,50 +141,116 @@ class MetadataContext {
|
|||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
public void wrapUp() {
|
||||
// IMPL NOTE : entityTypesByPersistentClass is a insertion-ordered map, where the insertion order
|
||||
// ensures that a type's super type is already processed...
|
||||
for ( Map.Entry<PersistentClass,EntityTypeImpl<?>> entry : entityTypesByPersistentClass.entrySet() ) {
|
||||
applyIdMetadata( entry.getKey(), entry.getValue() );
|
||||
applyVersionAttribute( entry.getKey(), entry.getValue() );
|
||||
Iterator<Property> properties = ( Iterator<Property> ) entry.getKey().getPropertyIterator();
|
||||
while ( properties.hasNext() ) {
|
||||
final Property property = properties.next();
|
||||
final Attribute attribute = attributeFactory.buildAttribute( entry.getValue(), property );
|
||||
entry.getValue().getBuilder().addAttribute( attribute );
|
||||
//we need to process types from superclasses to subclasses
|
||||
for (Object mapping : orderedMappings) {
|
||||
if ( PersistentClass.class.isAssignableFrom( mapping.getClass() ) ) {
|
||||
@SuppressWarnings( "unchecked" )
|
||||
final PersistentClass safeMapping = (PersistentClass) mapping;
|
||||
final EntityTypeImpl<?> jpa2Mapping = entityTypesByPersistentClass.get( safeMapping );
|
||||
applyIdMetadata( safeMapping, jpa2Mapping );
|
||||
applyVersionAttribute( safeMapping, jpa2Mapping );
|
||||
Iterator<Property> properties = ( Iterator<Property> ) safeMapping.getDeclaredPropertyIterator();
|
||||
while ( properties.hasNext() ) {
|
||||
final Property property = properties.next();
|
||||
final Attribute attribute = attributeFactory.buildAttribute( jpa2Mapping, property, true );
|
||||
jpa2Mapping.getBuilder().addAttribute( attribute );
|
||||
}
|
||||
jpa2Mapping.lock();
|
||||
populateStaticMetamodel( jpa2Mapping );
|
||||
}
|
||||
else if ( MappedSuperclass.class.isAssignableFrom( mapping.getClass() ) ) {
|
||||
@SuppressWarnings( "unchecked" )
|
||||
final MappedSuperclass safeMapping = (MappedSuperclass) mapping;
|
||||
final MappedSuperclassTypeImpl<?> jpa2Mapping = mappedSuperclassByMappedSuperclassMapping.get(
|
||||
safeMapping
|
||||
);
|
||||
applyIdMetadata( safeMapping, jpa2Mapping );
|
||||
applyVersionAttribute( safeMapping, jpa2Mapping );
|
||||
Iterator<Property> properties = ( Iterator<Property> ) safeMapping.getDeclaredPropertyIterator();
|
||||
while ( properties.hasNext() ) {
|
||||
final Property property = properties.next();
|
||||
final Attribute attribute = attributeFactory.buildAttribute( jpa2Mapping, property, false );
|
||||
jpa2Mapping.getBuilder().addAttribute( attribute );
|
||||
}
|
||||
jpa2Mapping.lock();
|
||||
populateStaticMetamodel( jpa2Mapping );
|
||||
}
|
||||
else {
|
||||
throw new AssertionFailure( "Unexpected mapping type: " + mapping.getClass() );
|
||||
}
|
||||
entry.getValue().lock();
|
||||
populateStaticMetamodel( entry.getValue() );
|
||||
}
|
||||
}
|
||||
|
||||
private <X> void applyIdMetadata(PersistentClass persistentClass, EntityTypeImpl<X> jpaEntityType) {
|
||||
if ( persistentClass.hasIdentifierProperty() ) {
|
||||
jpaEntityType.getBuilder().applyIdAttribute(
|
||||
attributeFactory.buildIdAttribute( jpaEntityType, persistentClass.getIdentifierProperty() )
|
||||
);
|
||||
final Property declaredIdentifierProperty = persistentClass.getDeclaredIdentifierProperty();
|
||||
if (declaredIdentifierProperty != null) {
|
||||
jpaEntityType.getBuilder().applyIdAttribute(
|
||||
attributeFactory.buildIdAttribute( jpaEntityType, declaredIdentifierProperty, true )
|
||||
);
|
||||
}
|
||||
}
|
||||
else {
|
||||
jpaEntityType.getBuilder().applyIdClassAttributes( buildIdClassAttributes( jpaEntityType, persistentClass ) );
|
||||
}
|
||||
}
|
||||
|
||||
private <X> void applyVersionAttribute(PersistentClass persistentClass, EntityTypeImpl<X> jpaEntityType) {
|
||||
if ( ! persistentClass.isVersioned() ) {
|
||||
return;
|
||||
private <X> void applyIdMetadata(MappedSuperclass mappingType, MappedSuperclassTypeImpl<X> jpaMappingType) {
|
||||
if ( mappingType.hasIdentifierProperty() ) {
|
||||
final Property declaredIdentifierProperty = mappingType.getDeclaredIdentifierProperty();
|
||||
if (declaredIdentifierProperty != null) {
|
||||
jpaMappingType.getBuilder().applyIdAttribute(
|
||||
attributeFactory.buildIdAttribute( jpaMappingType, declaredIdentifierProperty, false )
|
||||
);
|
||||
}
|
||||
}
|
||||
//an MappedSuperclass can have no identifier if the id is set below in the hierarchy
|
||||
else if ( mappingType.getIdentifierMapper() != null ){
|
||||
final Set<SingularAttribute<? super X, ?>> attributes = buildIdClassAttributes(
|
||||
jpaMappingType, mappingType
|
||||
);
|
||||
jpaMappingType.getBuilder().applyIdClassAttributes( attributes );
|
||||
}
|
||||
}
|
||||
|
||||
private <X> void applyVersionAttribute(PersistentClass persistentClass, EntityTypeImpl<X> jpaEntityType) {
|
||||
final Property declaredVersion = persistentClass.getDeclaredVersion();
|
||||
if (declaredVersion != null) {
|
||||
jpaEntityType.getBuilder().applyVersionAttribute(
|
||||
attributeFactory.buildVersionAttribute( jpaEntityType, declaredVersion, true )
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
private <X> void applyVersionAttribute(MappedSuperclass mappingType, MappedSuperclassTypeImpl<X> jpaMappingType) {
|
||||
final Property declaredVersion = mappingType.getDeclaredVersion();
|
||||
if ( declaredVersion != null ) {
|
||||
jpaMappingType.getBuilder().applyVersionAttribute(
|
||||
attributeFactory.buildVersionAttribute( jpaMappingType, declaredVersion, false )
|
||||
);
|
||||
}
|
||||
jpaEntityType.getBuilder().applyVersionAttribute(
|
||||
attributeFactory.buildVerisonAttribute( jpaEntityType, persistentClass.getVersion() )
|
||||
);
|
||||
}
|
||||
|
||||
@SuppressWarnings( "unchecked")
|
||||
private <X> Set<SingularAttribute<? super X, ?>> buildIdClassAttributes(
|
||||
EntityTypeImpl<X> jpaEntityType,
|
||||
PersistentClass persistentClass) {
|
||||
Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
|
||||
@SuppressWarnings( "unchecked")
|
||||
Iterator<Property> properties = persistentClass.getIdentifierMapper().getPropertyIterator();
|
||||
while ( properties.hasNext() ) {
|
||||
attributes.add( attributeFactory.buildIdAttribute( jpaEntityType, properties.next() ) );
|
||||
attributes.add( attributeFactory.buildIdAttribute( jpaEntityType, properties.next(), true ) );
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
||||
private <X> Set<SingularAttribute<? super X, ?>> buildIdClassAttributes(
|
||||
MappedSuperclassTypeImpl<X> jpaMappingType,
|
||||
MappedSuperclass mappingType) {
|
||||
Set<SingularAttribute<? super X, ?>> attributes = new HashSet<SingularAttribute<? super X, ?>>();
|
||||
@SuppressWarnings( "unchecked" )
|
||||
Iterator<Property> properties = mappingType.getIdentifierMapper().getPropertyIterator();
|
||||
while ( properties.hasNext() ) {
|
||||
attributes.add( attributeFactory.buildIdAttribute( jpaMappingType, properties.next(), false ) );
|
||||
}
|
||||
return attributes;
|
||||
}
|
||||
|
@ -206,4 +285,7 @@ class MetadataContext {
|
|||
// push the attributes on to the metamodel class...
|
||||
}
|
||||
|
||||
public MappedSuperclassTypeImpl<?> locateMappedSuperclassType(MappedSuperclass mappedSuperclass) {
|
||||
return mappedSuperclassByMappedSuperclassMapping.get(mappedSuperclass);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -32,6 +32,7 @@ import javax.persistence.metamodel.ManagedType;
|
|||
import javax.persistence.metamodel.EmbeddableType;
|
||||
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
|
||||
/**
|
||||
|
@ -46,7 +47,7 @@ public class MetamodelImpl implements Metamodel, Serializable {
|
|||
|
||||
/**
|
||||
* Build the metamodel using the information from the collection of Hibernate
|
||||
* {@link PersistentClass} models as well as the Hibernate {@link SessionFactory}.
|
||||
* {@link PersistentClass} models as well as the Hibernate {@link org.hibernate.SessionFactory}.
|
||||
*
|
||||
* @param persistentClasses Iterator over the Hibernate (config-time) metamodel
|
||||
* @param sessionFactory The Hibernate session factry.
|
||||
|
@ -74,16 +75,24 @@ public class MetamodelImpl implements Metamodel, Serializable {
|
|||
return entityType;
|
||||
}
|
||||
|
||||
@SuppressWarnings({ "unchecked" })
|
||||
//TODO remove / reduce @SW scope
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private static EntityTypeImpl<?> buildEntityType(PersistentClass persistentClass, MetadataContext context) {
|
||||
final PersistentClass superPersistentClass = persistentClass.getSuperclass();
|
||||
final EntityTypeImpl superEntityType = superPersistentClass == null
|
||||
final MappedSuperclass superMappedSuperclass = persistentClass.getSuperMappedSuperclass();
|
||||
AbstractIdentifiableType<?> superType = superMappedSuperclass == null
|
||||
? null
|
||||
: locateOrBuildEntityType( superPersistentClass, context );
|
||||
: locateOrBuildMappedsuperclassType( superMappedSuperclass, context );
|
||||
//no mappedSuperclass, check for a super entity
|
||||
if (superType == null) {
|
||||
final PersistentClass superPersistentClass = persistentClass.getSuperclass();
|
||||
superType = superPersistentClass == null
|
||||
? null
|
||||
: locateOrBuildEntityType( superPersistentClass, context );
|
||||
}
|
||||
final Class javaType = persistentClass.getMappedClass();
|
||||
EntityTypeImpl entityType = new EntityTypeImpl(
|
||||
javaType,
|
||||
superEntityType,
|
||||
superType,
|
||||
persistentClass.getClassName(),
|
||||
persistentClass.hasIdentifierProperty(),
|
||||
persistentClass.isVersioned()
|
||||
|
@ -92,6 +101,41 @@ public class MetamodelImpl implements Metamodel, Serializable {
|
|||
return entityType;
|
||||
}
|
||||
|
||||
private static MappedSuperclassTypeImpl<?> locateOrBuildMappedsuperclassType(
|
||||
MappedSuperclass mappedSuperclass, MetadataContext context) {
|
||||
MappedSuperclassTypeImpl<?> mappedSuperclassType = context.locateMappedSuperclassType( mappedSuperclass );
|
||||
if ( mappedSuperclassType == null ) {
|
||||
mappedSuperclassType = buildMappedSuperclassType(mappedSuperclass, context);
|
||||
}
|
||||
return mappedSuperclassType;
|
||||
}
|
||||
|
||||
//TODO remove / reduce @SW scope
|
||||
@SuppressWarnings( "unchecked" )
|
||||
private static MappedSuperclassTypeImpl<?> buildMappedSuperclassType(MappedSuperclass mappedSuperclass,
|
||||
MetadataContext context) {
|
||||
final MappedSuperclass superMappedSuperclass = mappedSuperclass.getSuperMappedSuperclass();
|
||||
AbstractIdentifiableType<?> superType = superMappedSuperclass == null
|
||||
? null
|
||||
: locateOrBuildMappedsuperclassType( superMappedSuperclass, context );
|
||||
//no mappedSuperclass, check for a super entity
|
||||
if (superType == null) {
|
||||
final PersistentClass superPersistentClass = mappedSuperclass.getSuperPersistentClass();
|
||||
superType = superPersistentClass == null
|
||||
? null
|
||||
: locateOrBuildEntityType( superPersistentClass, context );
|
||||
}
|
||||
final Class javaType = mappedSuperclass.getMappedClass();
|
||||
MappedSuperclassTypeImpl mappedSuperclassType = new MappedSuperclassTypeImpl(
|
||||
javaType,
|
||||
superType,
|
||||
mappedSuperclass.hasIdentifierProperty(),
|
||||
mappedSuperclass.isVersioned()
|
||||
);
|
||||
context.registerMappedSuperclassType( mappedSuperclass, mappedSuperclassType );
|
||||
return mappedSuperclassType;
|
||||
}
|
||||
|
||||
/**
|
||||
* Instantiate the metamodel.
|
||||
*
|
||||
|
|
|
@ -0,0 +1,31 @@
|
|||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Id;
|
||||
import javax.persistence.GeneratedValue;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class Animal extends SubThing {
|
||||
private Long id;
|
||||
private int legNbr;
|
||||
|
||||
@Id @GeneratedValue
|
||||
public Long getId() {
|
||||
return id;
|
||||
}
|
||||
|
||||
public void setId(Long id) {
|
||||
this.id = id;
|
||||
}
|
||||
|
||||
public int getLegNbr() {
|
||||
return legNbr;
|
||||
}
|
||||
|
||||
public void setLegNbr(int legNbr) {
|
||||
this.legNbr = legNbr;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class Cat extends Cattish {
|
||||
private String nickname;
|
||||
|
||||
public String getNickname() {
|
||||
return nickname;
|
||||
}
|
||||
|
||||
public void setNickname(String nickname) {
|
||||
this.nickname = nickname;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class Cattish extends Feline {
|
||||
private long hoursOfSleep;
|
||||
|
||||
public long getHoursOfSleep() {
|
||||
return hoursOfSleep;
|
||||
}
|
||||
|
||||
public void setHoursOfSleep(long hoursOfSleep) {
|
||||
this.hoursOfSleep = hoursOfSleep;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class Dog extends Animal {
|
||||
private String name;
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@Entity
|
||||
public class Feline extends Animal {
|
||||
private String color;
|
||||
|
||||
public String getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
public void setColor(String color) {
|
||||
this.color = color;
|
||||
}
|
||||
}
|
|
@ -12,6 +12,9 @@ import javax.persistence.metamodel.SetAttribute;
|
|||
import javax.persistence.metamodel.PluralAttribute;
|
||||
import javax.persistence.metamodel.MapAttribute;
|
||||
import javax.persistence.metamodel.ListAttribute;
|
||||
import javax.persistence.metamodel.MappedSuperclassType;
|
||||
import javax.persistence.metamodel.CollectionAttribute;
|
||||
import javax.persistence.metamodel.IdentifiableType;
|
||||
|
||||
import org.hibernate.ejb.test.TestCase;
|
||||
|
||||
|
@ -53,6 +56,8 @@ public class MetadataTest extends TestCase {
|
|||
assertFalse( fridgeType.hasVersionAttribute() );
|
||||
assertEquals( Type.PersistenceType.ENTITY, fridgeType.getPersistenceType() );
|
||||
|
||||
assertEquals( 3, fridgeType.getDeclaredAttributes().size() );
|
||||
|
||||
final EntityType<House> houseType = factory.getMetamodel().entity( House.class );
|
||||
assertTrue( houseType.hasSingleIdAttribute() );
|
||||
final SingularAttribute<House, House.Key> houseId = houseType.getDeclaredId( House.Key.class );
|
||||
|
@ -74,6 +79,7 @@ public class MetadataTest extends TestCase {
|
|||
final SingularAttribute<? super FoodItem, Long> version = foodType.getVersion( Long.class );
|
||||
assertNotNull( version );
|
||||
assertTrue( version.isVersion() );
|
||||
assertEquals( 3, foodType.getDeclaredAttributes().size() );
|
||||
|
||||
}
|
||||
|
||||
|
@ -158,7 +164,84 @@ public class MetadataTest extends TestCase {
|
|||
assertEquals( PluralAttribute.CollectionType.LIST, roomsBySize.getCollectionType() );
|
||||
}
|
||||
|
||||
//todo test plural
|
||||
public void testHierarchy() {
|
||||
final EntityType<Cat> cat = factory.getMetamodel().entity( Cat.class );
|
||||
assertNotNull( cat );
|
||||
assertEquals( 7, cat.getAttributes().size() );
|
||||
assertEquals( 1, cat.getDeclaredAttributes().size() );
|
||||
|
||||
assertTrue( cat.hasVersionAttribute() );
|
||||
assertEquals( "version", cat.getVersion(Long.class).getName() );
|
||||
verifyDeclaredVersiobnNotPresent( cat );
|
||||
verifyDeclaredIdNotPresentAndIdPresent(cat);
|
||||
|
||||
assertEquals( Type.PersistenceType.MAPPED_SUPERCLASS, cat.getSupertype().getPersistenceType() );
|
||||
MappedSuperclassType<Cattish> cattish = (MappedSuperclassType<Cattish>) cat.getSupertype();
|
||||
assertEquals( 6, cattish.getAttributes().size() );
|
||||
assertEquals( 1, cattish.getDeclaredAttributes().size() );
|
||||
|
||||
assertTrue( cattish.hasVersionAttribute() );
|
||||
assertEquals( "version", cattish.getVersion(Long.class).getName() );
|
||||
verifyDeclaredVersiobnNotPresent( cattish );
|
||||
verifyDeclaredIdNotPresentAndIdPresent(cattish);
|
||||
|
||||
assertEquals( Type.PersistenceType.ENTITY, cattish.getSupertype().getPersistenceType() );
|
||||
EntityType<Feline> feline = (EntityType<Feline>) cattish.getSupertype();
|
||||
assertEquals( 5, feline.getAttributes().size() );
|
||||
assertEquals( 1, feline.getDeclaredAttributes().size() );
|
||||
|
||||
assertTrue( feline.hasVersionAttribute() );
|
||||
assertEquals( "version", feline.getVersion(Long.class).getName() );
|
||||
verifyDeclaredVersiobnNotPresent( feline );
|
||||
verifyDeclaredIdNotPresentAndIdPresent(feline);
|
||||
|
||||
assertEquals( Type.PersistenceType.MAPPED_SUPERCLASS, feline.getSupertype().getPersistenceType() );
|
||||
MappedSuperclassType<Animal> animal = (MappedSuperclassType<Animal>) feline.getSupertype();
|
||||
assertEquals( 4, animal.getAttributes().size() );
|
||||
assertEquals( 2, animal.getDeclaredAttributes().size() );
|
||||
|
||||
assertTrue( animal.hasVersionAttribute() );
|
||||
assertEquals( "version", animal.getVersion(Long.class).getName() );
|
||||
verifyDeclaredVersiobnNotPresent( animal );
|
||||
assertEquals( "id", animal.getId(Long.class).getName() );
|
||||
assertEquals( "id", animal.getDeclaredId(Long.class).getName() );
|
||||
|
||||
assertEquals( Type.PersistenceType.MAPPED_SUPERCLASS, animal.getSupertype().getPersistenceType() );
|
||||
MappedSuperclassType<Thing> thing = (MappedSuperclassType<Thing>) animal.getSupertype();
|
||||
assertEquals( 2, thing.getAttributes().size() );
|
||||
assertEquals( 2, thing.getDeclaredAttributes().size() );
|
||||
final SingularAttribute<Thing, Double> weight = thing.getDeclaredSingularAttribute( "weight", Double.class );
|
||||
assertEquals( Double.class, weight.getJavaType() );
|
||||
|
||||
assertEquals( "version", thing.getVersion(Long.class).getName() );
|
||||
assertEquals( "version", thing.getDeclaredVersion(Long.class).getName() );
|
||||
assertNull( thing.getId( Long.class ) );
|
||||
|
||||
assertNull( thing.getSupertype() );
|
||||
}
|
||||
|
||||
private void verifyDeclaredIdNotPresentAndIdPresent(IdentifiableType<?> type) {
|
||||
assertEquals( "id", type.getId(Long.class).getName() );
|
||||
try {
|
||||
type.getDeclaredId(Long.class);
|
||||
fail("Should not have a declared id");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
//success
|
||||
}
|
||||
}
|
||||
|
||||
private void verifyDeclaredVersiobnNotPresent(IdentifiableType<?> type) {
|
||||
try {
|
||||
type.getDeclaredVersion(Long.class);
|
||||
fail("Should not have a declared version");
|
||||
}
|
||||
catch (IllegalArgumentException e) {
|
||||
//success
|
||||
}
|
||||
}
|
||||
|
||||
//todo test plural
|
||||
|
||||
@Override
|
||||
public Class[] getAnnotatedClasses() {
|
||||
|
@ -166,7 +249,11 @@ public class MetadataTest extends TestCase {
|
|||
Fridge.class,
|
||||
FoodItem.class,
|
||||
Person.class,
|
||||
House.class
|
||||
House.class,
|
||||
Dog.class,
|
||||
Cat.class,
|
||||
Cattish.class,
|
||||
Feline.class
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
//not an entity but in between mapped superclass and entity
|
||||
public class SubThing extends Thing {
|
||||
private String blah;
|
||||
|
||||
public String getBlah() {
|
||||
return blah;
|
||||
}
|
||||
|
||||
public void setBlah(String blah) {
|
||||
this.blah = blah;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,30 @@
|
|||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
import javax.persistence.Version;
|
||||
|
||||
/**
|
||||
* @author Emmanuel Bernard
|
||||
*/
|
||||
@MappedSuperclass
|
||||
public class Thing {
|
||||
private Double weight;
|
||||
private Long version;
|
||||
|
||||
public Double getWeight() {
|
||||
return weight;
|
||||
}
|
||||
|
||||
public void setWeight(Double weight) {
|
||||
this.weight = weight;
|
||||
}
|
||||
|
||||
@Version
|
||||
public Long getVersion() {
|
||||
return version;
|
||||
}
|
||||
|
||||
public void setVersion(Long version) {
|
||||
this.version = version;
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue