HHH-4202 - Implement JPA 2.0 metamodel APIs
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@17886 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
2dc911855b
commit
255b7076b8
|
@ -189,6 +189,10 @@ public abstract class AbstractIdentifiableType<X>
|
|||
return isVersioned;
|
||||
}
|
||||
|
||||
public boolean hasDeclaredVersionAttribute() {
|
||||
return isVersioned && version != null;
|
||||
}
|
||||
|
||||
/**
|
||||
* {@inheritDoc}
|
||||
*/
|
||||
|
@ -222,6 +226,16 @@ public abstract class AbstractIdentifiableType<X>
|
|||
return ( SingularAttribute<X, Y> ) version;
|
||||
}
|
||||
|
||||
/**
|
||||
* For used to retrieve the declared version when populating the static metamodel.
|
||||
*
|
||||
* @return The declared
|
||||
*/
|
||||
public SingularAttribute<X, ?> getDeclaredVersion() {
|
||||
checkDeclaredVersion();
|
||||
return version;
|
||||
}
|
||||
|
||||
/**
|
||||
* Centralized check to ensure the version (if one) is actually declared on the class mapped here, as opposed to a
|
||||
* super class.
|
||||
|
|
|
@ -29,16 +29,17 @@ import java.util.Map;
|
|||
import java.util.Set;
|
||||
import java.util.List;
|
||||
import java.util.ArrayList;
|
||||
import java.lang.reflect.Field;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
import javax.persistence.metamodel.SingularAttribute;
|
||||
import javax.swing.*;
|
||||
import javax.persistence.metamodel.IdentifiableType;
|
||||
|
||||
import org.hibernate.mapping.MappedSuperclass;
|
||||
import org.hibernate.mapping.PersistentClass;
|
||||
import org.hibernate.mapping.Property;
|
||||
import org.hibernate.mapping.Component;
|
||||
import org.hibernate.engine.SessionFactoryImplementor;
|
||||
import org.hibernate.annotations.common.AssertionFailure;
|
||||
import org.hibernate.AnnotationException;
|
||||
|
||||
/**
|
||||
* Defines a context for storing information during the building of the {@link MetamodelImpl}.
|
||||
|
@ -163,6 +164,12 @@ class MetadataContext {
|
|||
Iterator<Property> properties = ( Iterator<Property> ) safeMapping.getDeclaredPropertyIterator();
|
||||
while ( properties.hasNext() ) {
|
||||
final Property property = properties.next();
|
||||
if ( property.getValue() == safeMapping.getIdentifierMapper() ) {
|
||||
// property represents special handling for id-class mappings but we have already
|
||||
// accounted for the embedded property mappings in #applyIdMetadata &&
|
||||
// #buildIdClassAttributes
|
||||
continue;
|
||||
}
|
||||
final Attribute attribute = attributeFactory.buildAttribute( jpa2Mapping, property, true );
|
||||
jpa2Mapping.getBuilder().addAttribute( attribute );
|
||||
}
|
||||
|
@ -190,7 +197,12 @@ class MetadataContext {
|
|||
throw new AssertionFailure( "Unexpected mapping type: " + mapping.getClass() );
|
||||
}
|
||||
}
|
||||
|
||||
for ( EmbeddableTypeImpl embeddable : embeddables.values() ) {
|
||||
populateStaticMetamodel( embeddable );
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private <X> void applyIdMetadata(PersistentClass persistentClass, EntityTypeImpl<X> jpaEntityType) {
|
||||
if ( persistentClass.hasIdentifierProperty() ) {
|
||||
|
@ -289,11 +301,55 @@ class MetadataContext {
|
|||
private final Set<Class> processedMetamodelClasses = new HashSet<Class>();
|
||||
|
||||
private <X> void registerAttributes(Class metamodelClass, AbstractManagedType<X> managedType) {
|
||||
if ( processedMetamodelClasses.add( metamodelClass ) ) {
|
||||
if ( ! processedMetamodelClasses.add( metamodelClass ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
// push the attributes on to the metamodel class...
|
||||
for ( Attribute<X, ?> attribute : managedType.getDeclaredAttributes() ) {
|
||||
registerAttribute( metamodelClass, attribute );
|
||||
}
|
||||
|
||||
if ( IdentifiableType.class.isInstance( managedType ) ) {
|
||||
final AbstractIdentifiableType<X> entityType = ( AbstractIdentifiableType<X> ) managedType;
|
||||
|
||||
// handle version
|
||||
if ( entityType.hasDeclaredVersionAttribute() ) {
|
||||
registerAttribute( metamodelClass, entityType.getDeclaredVersion() );
|
||||
}
|
||||
|
||||
// handle id-class mappings specially
|
||||
if ( ! entityType.hasSingleIdAttribute() ) {
|
||||
final Set<SingularAttribute<? super X, ?>> attributes = entityType.getIdClassAttributes();
|
||||
if ( attributes != null ) {
|
||||
for ( SingularAttribute<? super X, ?> attribute : attributes ) {
|
||||
registerAttribute( metamodelClass, attribute );
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private <X> void registerAttribute(Class metamodelClass, Attribute<X, ?> attribute) {
|
||||
final String name = attribute.getName();
|
||||
try {
|
||||
Field field = metamodelClass.getDeclaredField( name );
|
||||
field.setAccessible( true ); // should be public anyway, but to be sure...
|
||||
field.set( null, attribute );
|
||||
}
|
||||
catch ( NoSuchFieldException e ) {
|
||||
// todo : exception type?
|
||||
throw new AssertionFailure(
|
||||
"Unable to locate static metamodel field : " + metamodelClass.getName() + '#' + name
|
||||
);
|
||||
}
|
||||
catch ( IllegalAccessException e ) {
|
||||
// todo : exception type?
|
||||
throw new AssertionFailure(
|
||||
"Unable to inject static metamodel attribute : " + metamodelClass.getName() + '#' + name,
|
||||
e
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
public MappedSuperclassTypeImpl<?> locateMappedSuperclassType(MappedSuperclass mappedSuperclass) {
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.Entity;
|
||||
|
|
|
@ -0,0 +1,134 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import java.util.Set;
|
||||
import javax.persistence.metamodel.Attribute;
|
||||
import javax.persistence.metamodel.Bindable;
|
||||
import javax.persistence.metamodel.EmbeddableType;
|
||||
import javax.persistence.metamodel.PluralAttribute;
|
||||
import javax.persistence.metamodel.Type;
|
||||
|
||||
import org.hibernate.ejb.test.TestCase;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
public class StaticMetadataTest extends TestCase {
|
||||
|
||||
public void testInjections() throws Exception {
|
||||
// Address (embeddable)
|
||||
assertNotNull( Address_.address1 );
|
||||
assertNotNull( Address_.address2 );
|
||||
assertNotNull( Address_.city );
|
||||
final EmbeddableType<Address> addressType = (EmbeddableType<Address>) House_.address.getType();
|
||||
assertEquals( addressType.getDeclaredSingularAttribute( "address1" ), Address_.address1 );
|
||||
assertEquals( addressType.getDeclaredSingularAttribute( "address2" ), Address_.address2 );
|
||||
assertTrue( Address_.address1.isOptional() );
|
||||
assertFalse( Address_.address2.isOptional() );
|
||||
|
||||
// Animal (mapped superclass)
|
||||
assertNotNull( Animal_.id );
|
||||
assertTrue( Animal_.id.isId() );
|
||||
assertEquals( Long.class, Animal_.id.getJavaType() );
|
||||
assertNotNull( Animal_.legNbr );
|
||||
assertEquals( Integer.class, Animal_.legNbr.getJavaType() );
|
||||
|
||||
// Cat (hierarchy)
|
||||
assertNotNull( Cat_.id );
|
||||
assertNotNull( Cat_.id.isId() );
|
||||
assertEquals( Animal.class, Cat_.id.getJavaMember().getDeclaringClass() );
|
||||
assertNotNull( Cat_.nickname );
|
||||
|
||||
// FoodItem
|
||||
assertNotNull( FoodItem_.version );
|
||||
assertTrue( FoodItem_.version.isVersion() );
|
||||
|
||||
// Fridge
|
||||
assertNotNull( Fridge_.id );
|
||||
assertTrue( Fridge_.id.isId() );
|
||||
assertEquals( Long.class, Fridge_.id.getJavaType() );
|
||||
assertNotNull( Fridge_.temperature );
|
||||
assertEquals( "temperature", Fridge_.temperature.getName() );
|
||||
assertEquals( Fridge.class, Fridge_.temperature.getDeclaringType().getJavaType() );
|
||||
assertEquals( Integer.class, Fridge_.temperature.getJavaType() );
|
||||
assertEquals( Integer.class, Fridge_.temperature.getBindableJavaType() );
|
||||
assertEquals( Integer.class, Fridge_.temperature.getType().getJavaType() );
|
||||
assertEquals( Bindable.BindableType.SINGULAR_ATTRIBUTE, Fridge_.temperature.getBindableType() );
|
||||
assertEquals( Type.PersistenceType.BASIC, Fridge_.temperature.getType().getPersistenceType() );
|
||||
assertEquals( Attribute.PersistentAttributeType.BASIC, Fridge_.temperature.getPersistentAttributeType() );
|
||||
assertFalse( Fridge_.temperature.isId() );
|
||||
assertFalse( Fridge_.temperature.isOptional() );
|
||||
assertFalse( Fridge_.temperature.isAssociation() );
|
||||
assertFalse( Fridge_.temperature.isCollection() );
|
||||
assertFalse( Fridge_.brand.isOptional() );
|
||||
|
||||
// House (embedded id)
|
||||
assertNotNull( House_.key );
|
||||
assertTrue( House_.key.isId() );
|
||||
assertEquals( Attribute.PersistentAttributeType.EMBEDDED, House_.key.getPersistentAttributeType() );
|
||||
assertNotNull( House_.address );
|
||||
assertEquals( Attribute.PersistentAttributeType.EMBEDDED, House_.address.getPersistentAttributeType() );
|
||||
assertFalse( House_.address.isCollection() );
|
||||
assertFalse( House_.address.isAssociation() );
|
||||
assertNotNull( House_.rooms );
|
||||
assertTrue( House_.rooms.isAssociation() );
|
||||
assertTrue( House_.rooms.isCollection() );
|
||||
assertEquals( Attribute.PersistentAttributeType.ELEMENT_COLLECTION, House_.rooms.getPersistentAttributeType() );
|
||||
assertEquals( Room.class, House_.rooms.getBindableJavaType() );
|
||||
assertEquals( Bindable.BindableType.PLURAL_ATTRIBUTE, House_.rooms.getBindableType() );
|
||||
assertEquals( Set.class, House_.rooms.getJavaType() );
|
||||
assertEquals( PluralAttribute.CollectionType.SET, House_.rooms.getCollectionType() );
|
||||
assertEquals( Type.PersistenceType.EMBEDDABLE, House_.rooms.getElementType().getPersistenceType() );
|
||||
assertNotNull( House_.roomsByName );
|
||||
assertEquals( String.class, House_.roomsByName.getKeyJavaType() );
|
||||
assertEquals( Type.PersistenceType.BASIC, House_.roomsByName.getKeyType().getPersistenceType() );
|
||||
assertEquals( PluralAttribute.CollectionType.MAP, House_.roomsByName.getCollectionType() );
|
||||
assertNotNull( House_.roomsBySize );
|
||||
assertEquals( Type.PersistenceType.EMBEDDABLE, House_.roomsBySize.getElementType().getPersistenceType() );
|
||||
assertEquals( PluralAttribute.CollectionType.LIST, House_.roomsBySize.getCollectionType() );
|
||||
|
||||
// Person (mapped id)
|
||||
assertNotNull( Person_.firstName );
|
||||
assertNotNull( Person_.lastName );
|
||||
assertTrue( Person_.firstName.isId() );
|
||||
assertTrue( Person_.lastName.isId() );
|
||||
assertTrue( Person_.lastName.isId() );
|
||||
}
|
||||
|
||||
@Override
|
||||
public Class[] getAnnotatedClasses() {
|
||||
return new Class[]{
|
||||
Fridge.class,
|
||||
FoodItem.class,
|
||||
Person.class,
|
||||
House.class,
|
||||
Dog.class,
|
||||
Cat.class,
|
||||
Cattish.class,
|
||||
Feline.class
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -1,3 +1,26 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2009 by Red Hat Inc and/or its affiliates or by
|
||||
* third-party contributors as indicated by either @author tags or express
|
||||
* copyright attribution statements applied by the authors. All
|
||||
* third-party contributions are distributed under license by Red Hat Inc.
|
||||
*
|
||||
* This copyrighted material is made available to anyone wishing to use, modify,
|
||||
* copy, or redistribute it subject to the terms and conditions of the GNU
|
||||
* Lesser General Public License, as published by the Free Software Foundation.
|
||||
*
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY
|
||||
* or FITNESS FOR A PARTICULAR PURPOSE. See the GNU Lesser General Public License
|
||||
* for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU Lesser General Public License
|
||||
* along with this distribution; if not, write to:
|
||||
* Free Software Foundation, Inc.
|
||||
* 51 Franklin Street, Fifth Floor
|
||||
* Boston, MA 02110-1301 USA
|
||||
*/
|
||||
package org.hibernate.ejb.test.metadata;
|
||||
|
||||
import javax.persistence.MappedSuperclass;
|
||||
|
|
Loading…
Reference in New Issue