HHH-6173 Some initial refactorings to start processing @Embedded and @Embeddable
This commit is contained in:
parent
7700719306
commit
1e88107f3e
|
@ -24,7 +24,7 @@
|
|||
package org.hibernate.metamodel.domain;
|
||||
|
||||
/**
|
||||
* Desribes an attribute.
|
||||
* Describes an attribute.
|
||||
*
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
|
|
|
@ -120,7 +120,6 @@ public class AnnotationBinder implements Binder {
|
|||
return classLoaderService;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public void bindIndependentMetadata(MetadataSources sources) {
|
||||
TypeDefBinder.bind( metadata, index );
|
||||
|
|
|
@ -0,0 +1,56 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @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.metamodel.source.annotations.entity;
|
||||
|
||||
|
||||
import org.jboss.jandex.Index;
|
||||
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
/**
|
||||
* Helper class for keeping some context information needed during the processing of mapped classes.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class AnnotationBindingContext {
|
||||
private final ServiceRegistry serviceRegistry;
|
||||
private final Index index;
|
||||
|
||||
private ClassLoaderService classLoaderService;
|
||||
|
||||
public AnnotationBindingContext(Index index, ServiceRegistry serviceRegistry) {
|
||||
this.index = index;
|
||||
this.serviceRegistry = serviceRegistry;
|
||||
}
|
||||
|
||||
public ClassLoaderService classLoaderService() {
|
||||
if ( classLoaderService == null ) {
|
||||
classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
}
|
||||
return classLoaderService;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -41,16 +41,16 @@ import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
|||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class AssociationAttribute extends SimpleAttribute {
|
||||
private final AssociationType associationType;
|
||||
private final AttributeType associationType;
|
||||
private final boolean ignoreNotFound;
|
||||
private final String referencedEntityType;
|
||||
private final Set<CascadeType> cascadeTypes;
|
||||
|
||||
public static AssociationAttribute createAssociationAttribute(String name, String type, AssociationType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
public static AssociationAttribute createAssociationAttribute(String name, String type, AttributeType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
return new AssociationAttribute( name, type, associationType, annotations );
|
||||
}
|
||||
|
||||
private AssociationAttribute(String name, String type, AssociationType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
private AssociationAttribute(String name, String type, AttributeType associationType, Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
super( name, type, annotations, false );
|
||||
this.associationType = associationType;
|
||||
this.ignoreNotFound = ignoreNotFound();
|
||||
|
@ -72,7 +72,7 @@ public class AssociationAttribute extends SimpleAttribute {
|
|||
return referencedEntityType;
|
||||
}
|
||||
|
||||
public AssociationType getAssociationType() {
|
||||
public AttributeType getAssociationType() {
|
||||
return associationType;
|
||||
}
|
||||
|
||||
|
|
|
@ -28,18 +28,21 @@ import org.jboss.jandex.DotName;
|
|||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
|
||||
/**
|
||||
* An enum defining the type of mapped attribute.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public enum AssociationType {
|
||||
NO_ASSOCIATION( null ),
|
||||
public enum AttributeType {
|
||||
BASIC( 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 );
|
||||
MANY_TO_MANY( JPADotNames.MANY_TO_MANY ),
|
||||
EMBEDDED( JPADotNames.EMBEDDED );
|
||||
|
||||
private final DotName annotationDotName;
|
||||
|
||||
AssociationType(DotName annotationDotName) {
|
||||
AttributeType(DotName annotationDotName) {
|
||||
this.annotationDotName = annotationDotName;
|
||||
}
|
||||
|
|
@ -29,6 +29,7 @@ import java.lang.reflect.Method;
|
|||
import java.lang.reflect.Type;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.EnumMap;
|
||||
import java.util.HashSet;
|
||||
import java.util.LinkedHashMap;
|
||||
import java.util.List;
|
||||
|
@ -55,8 +56,6 @@ import org.hibernate.metamodel.binding.InheritanceType;
|
|||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
/**
|
||||
* Represents an entity, mapped superclass or component configured via annotations/xml.
|
||||
|
@ -68,7 +67,15 @@ public class ConfiguredClass {
|
|||
* The parent of this configured class or {@code null} in case this configured class is the root of a hierarchy.
|
||||
*/
|
||||
private final ConfiguredClass parent;
|
||||
|
||||
/**
|
||||
* The Jandex class info for this configured class. Provides access to the annotation defined on this configured class.
|
||||
*/
|
||||
private final ClassInfo classInfo;
|
||||
|
||||
/**
|
||||
* The actual java type.
|
||||
*/
|
||||
private final Class<?> clazz;
|
||||
|
||||
private final boolean isRoot;
|
||||
|
@ -83,19 +90,24 @@ public class ConfiguredClass {
|
|||
private final IdType idType;
|
||||
|
||||
private final Map<String, MappedAttribute> mappedAttributes;
|
||||
private final Set<String> transientFieldNames = new HashSet<String>();
|
||||
private final Set<String> transientMethodNames = new HashSet<String>();
|
||||
|
||||
private final AnnotationBindingContext context;
|
||||
|
||||
public ConfiguredClass(ClassInfo info,
|
||||
ConfiguredClass parent,
|
||||
AccessType hierarchyAccessType,
|
||||
InheritanceType inheritanceType,
|
||||
ServiceRegistry serviceRegistry,
|
||||
ResolvedTypeWithMembers resolvedType) {
|
||||
ResolvedTypeWithMembers resolvedType,
|
||||
AnnotationBindingContext context) {
|
||||
this.context = context;
|
||||
this.classInfo = info;
|
||||
this.parent = parent;
|
||||
this.isRoot = parent == null;
|
||||
this.hierarchyAccessType = hierarchyAccessType;
|
||||
this.inheritanceType = inheritanceType;
|
||||
this.clazz = serviceRegistry.getService( ClassLoaderService.class ).classForName( info.toString() );
|
||||
this.clazz = context.classLoaderService().classForName( info.toString() );
|
||||
|
||||
this.configuredClassType = determineType();
|
||||
this.classAccessType = determineClassAccessType();
|
||||
|
@ -104,6 +116,9 @@ public class ConfiguredClass {
|
|||
this.hasOwnTable = definesItsOwnTable();
|
||||
this.primaryTableName = determinePrimaryTableName();
|
||||
|
||||
// find transient field and method names
|
||||
findTransientFieldAndMethodNames();
|
||||
|
||||
List<MappedAttribute> simpleProps = collectAttributes( resolvedType );
|
||||
// make sure the properties are ordered by property name
|
||||
Collections.sort( simpleProps );
|
||||
|
@ -213,11 +228,6 @@ public class ConfiguredClass {
|
|||
* @return A list of the persistent properties of this configured class
|
||||
*/
|
||||
private List<MappedAttribute> collectAttributes(ResolvedTypeWithMembers resolvedTypes) {
|
||||
// create sets of transient field and method names
|
||||
Set<String> transientFieldNames = new HashSet<String>();
|
||||
Set<String> transientMethodNames = new HashSet<String>();
|
||||
populateTransientFieldAndMethodLists( transientFieldNames, transientMethodNames );
|
||||
|
||||
// use the class mate library to generic types
|
||||
ResolvedTypeWithMembers resolvedType = null;
|
||||
for ( HierarchicType hierarchicType : resolvedTypes.allTypesAndOverrides() ) {
|
||||
|
@ -381,15 +391,19 @@ public class ConfiguredClass {
|
|||
);
|
||||
|
||||
MappedAttribute attribute;
|
||||
AssociationType associationType = determineAssociationType( annotations );
|
||||
switch ( associationType ) {
|
||||
case NO_ASSOCIATION: {
|
||||
AttributeType attributeType = determineAttributeType( annotations );
|
||||
switch ( attributeType ) {
|
||||
case BASIC: {
|
||||
attribute = SimpleAttribute.createSimpleAttribute( name, ( (Class) type ).getName(), annotations );
|
||||
break;
|
||||
}
|
||||
case EMBEDDED: {
|
||||
throw new HibernateException( "foo" );
|
||||
}
|
||||
// TODO handle the different association types
|
||||
default: {
|
||||
attribute = AssociationAttribute.createAssociationAttribute(
|
||||
name, ( (Class) type ).getName(), associationType, annotations
|
||||
name, ( (Class) type ).getName(), attributeType, annotations
|
||||
);
|
||||
}
|
||||
}
|
||||
|
@ -397,26 +411,47 @@ public class ConfiguredClass {
|
|||
return attribute;
|
||||
}
|
||||
|
||||
private AssociationType determineAssociationType(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE );
|
||||
AnnotationInstance oneToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY );
|
||||
AnnotationInstance manyToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_ONE );
|
||||
AnnotationInstance manyToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY );
|
||||
/**
|
||||
* Given the annotations defined on a persistent attribute this methods determines the attribute type.
|
||||
*
|
||||
* @param annotations the annotations defined on the persistent attribute
|
||||
*
|
||||
* @return an instance of the {@code AttributeType} enum
|
||||
*/
|
||||
private AttributeType determineAttributeType(Map<DotName, List<AnnotationInstance>> annotations) {
|
||||
EnumMap<AttributeType, AnnotationInstance> discoveredAttributeTypes =
|
||||
new EnumMap<AttributeType, AnnotationInstance>( AttributeType.class );
|
||||
|
||||
if ( oneToOne == null && oneToMany == null && manyToOne == null && manyToMany == null ) {
|
||||
return AssociationType.NO_ASSOCIATION;
|
||||
AnnotationInstance oneToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_ONE );
|
||||
if ( oneToOne != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.ONE_TO_ONE, oneToOne );
|
||||
}
|
||||
else if ( oneToOne != null && oneToMany == null && manyToOne == null && manyToMany == null ) {
|
||||
return AssociationType.ONE_TO_ONE;
|
||||
|
||||
AnnotationInstance oneToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.ONE_TO_MANY );
|
||||
if ( oneToMany != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.ONE_TO_MANY, oneToMany );
|
||||
}
|
||||
else if ( oneToOne == null && oneToMany != null && manyToOne == null && manyToMany == null ) {
|
||||
return AssociationType.ONE_TO_MANY;
|
||||
|
||||
AnnotationInstance manyToOne = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_ONE );
|
||||
if ( manyToOne != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.MANY_TO_ONE, manyToOne );
|
||||
}
|
||||
else if ( oneToOne == null && oneToMany == null && manyToOne != null && manyToMany == null ) {
|
||||
return AssociationType.MANY_TO_ONE;
|
||||
|
||||
AnnotationInstance manyToMany = JandexHelper.getSingleAnnotation( annotations, JPADotNames.MANY_TO_MANY );
|
||||
if ( manyToMany != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.MANY_TO_MANY, manyToMany );
|
||||
}
|
||||
else if ( oneToOne == null && oneToMany == null && manyToOne == null && manyToMany != null ) {
|
||||
return AssociationType.MANY_TO_MANY;
|
||||
|
||||
AnnotationInstance embedded = JandexHelper.getSingleAnnotation( annotations, JPADotNames.EMBEDDED );
|
||||
if ( embedded != null ) {
|
||||
discoveredAttributeTypes.put( AttributeType.EMBEDDED, embedded );
|
||||
}
|
||||
|
||||
if ( discoveredAttributeTypes.size() == 0 ) {
|
||||
return AttributeType.BASIC;
|
||||
}
|
||||
else if ( discoveredAttributeTypes.size() == 1 ) {
|
||||
return discoveredAttributeTypes.keySet().iterator().next();
|
||||
}
|
||||
else {
|
||||
throw new AnnotationException( "More than one association type configured for property " + getName() + " of class " + getName() );
|
||||
|
@ -435,11 +470,8 @@ public class ConfiguredClass {
|
|||
|
||||
/**
|
||||
* Populates the sets of transient field and method names.
|
||||
*
|
||||
* @param transientFieldNames Set to populate with the field names explicitly marked as @Transient
|
||||
* @param transientMethodNames set to populate with the method names explicitly marked as @Transient
|
||||
*/
|
||||
private void populateTransientFieldAndMethodLists(Set<String> transientFieldNames, Set<String> transientMethodNames) {
|
||||
private void findTransientFieldAndMethodNames() {
|
||||
List<AnnotationInstance> transientMembers = classInfo.annotations().get( JPADotNames.TRANSIENT );
|
||||
if ( transientMembers == null ) {
|
||||
return;
|
||||
|
@ -524,5 +556,3 @@ public class ConfiguredClass {
|
|||
return IdType.NONE;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,11 +39,10 @@ import org.hibernate.metamodel.binding.InheritanceType;
|
|||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.util.JandexHelper;
|
||||
import org.hibernate.metamodel.source.annotations.util.ReflectionHelper;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
/**
|
||||
* Represents the inheritance structure of the configured classes within a class hierarchy.
|
||||
* Contains information about the access and inheritance type for all classes within a class hierarchy.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
|
@ -52,23 +51,23 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
|||
private final InheritanceType inheritanceType;
|
||||
private final List<ConfiguredClass> configuredClasses;
|
||||
|
||||
public static ConfiguredClassHierarchy create(List<ClassInfo> classes, ServiceRegistry serviceRegistry) {
|
||||
return new ConfiguredClassHierarchy( classes, serviceRegistry );
|
||||
public static ConfiguredClassHierarchy create(List<ClassInfo> classes, AnnotationBindingContext context) {
|
||||
return new ConfiguredClassHierarchy( classes, context );
|
||||
}
|
||||
|
||||
private ConfiguredClassHierarchy(List<ClassInfo> classes, ServiceRegistry serviceRegistry) {
|
||||
private ConfiguredClassHierarchy(List<ClassInfo> classes, AnnotationBindingContext context) {
|
||||
defaultAccessType = determineDefaultAccessType( classes );
|
||||
inheritanceType = determineInheritanceType( classes );
|
||||
|
||||
ClassLoaderService classLoaderService = serviceRegistry.getService( ClassLoaderService.class );
|
||||
Class<?> clazz = classLoaderService.classForName( classes.get( classes.size() - 1 ).name().toString() );
|
||||
ResolvedTypeWithMembers resolvedMembers = ReflectionHelper.resolveMemberTypes( clazz );
|
||||
// the resolved type for the top level class in the hierarchy
|
||||
Class<?> clazz = context.classLoaderService().classForName( classes.get( classes.size() - 1 ).name().toString() );
|
||||
ResolvedTypeWithMembers resolvedType = ReflectionHelper.resolveMemberTypes( clazz );
|
||||
|
||||
configuredClasses = new ArrayList<ConfiguredClass>();
|
||||
ConfiguredClass parent = null;
|
||||
for ( ClassInfo info : classes ) {
|
||||
ConfiguredClass configuredClass = new ConfiguredClass(
|
||||
info, parent, defaultAccessType, inheritanceType, serviceRegistry, resolvedMembers
|
||||
info, parent, defaultAccessType, inheritanceType, resolvedType, context
|
||||
);
|
||||
configuredClasses.add( configuredClass );
|
||||
parent = configuredClass;
|
||||
|
@ -114,7 +113,7 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
|||
if ( idAnnotations == null || idAnnotations.size() == 0 ) {
|
||||
continue;
|
||||
}
|
||||
accessType = processIdAnnotations( idAnnotations );
|
||||
accessType = determineAccessTypeByIdPlacement( idAnnotations );
|
||||
}
|
||||
|
||||
if ( accessType == null ) {
|
||||
|
@ -124,7 +123,7 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
|||
return accessType;
|
||||
}
|
||||
|
||||
private AccessType processIdAnnotations(List<AnnotationInstance> idAnnotations) {
|
||||
private AccessType determineAccessTypeByIdPlacement(List<AnnotationInstance> idAnnotations) {
|
||||
AccessType accessType = null;
|
||||
for ( AnnotationInstance annotation : idAnnotations ) {
|
||||
AccessType tmpAccessType;
|
||||
|
@ -217,5 +216,3 @@ public class ConfiguredClassHierarchy implements Iterable<ConfiguredClass> {
|
|||
return builder.toString();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -39,7 +39,7 @@ import org.hibernate.metamodel.source.annotations.HibernateDotNames;
|
|||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class MappedAttribute implements Comparable<MappedAttribute> {
|
||||
public abstract class MappedAttribute implements Comparable<MappedAttribute> {
|
||||
/**
|
||||
* Annotations defined on the attribute, keyed against the annotation dot name.
|
||||
*/
|
||||
|
|
|
@ -36,9 +36,9 @@ import org.jboss.jandex.DotName;
|
|||
import org.jboss.jandex.Index;
|
||||
|
||||
import org.hibernate.AnnotationException;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.JPADotNames;
|
||||
import org.hibernate.metamodel.source.annotations.entity.ConfiguredClassHierarchy;
|
||||
import org.hibernate.metamodel.source.annotations.entity.AnnotationBindingContext;
|
||||
import org.hibernate.service.ServiceRegistry;
|
||||
import org.hibernate.service.classloading.spi.ClassLoaderService;
|
||||
|
||||
|
@ -95,11 +95,12 @@ public class ConfiguredClassHierarchyBuilder {
|
|||
}
|
||||
}
|
||||
|
||||
AnnotationBindingContext context = new AnnotationBindingContext(index, serviceRegistry);
|
||||
Set<ConfiguredClassHierarchy> hierarchies = new HashSet<ConfiguredClassHierarchy>();
|
||||
List<List<ClassInfo>> processedList = new ArrayList<List<ClassInfo>>();
|
||||
for ( List<ClassInfo> classInfoList : processedClassInfos.values() ) {
|
||||
if ( !processedList.contains( classInfoList ) ) {
|
||||
hierarchies.add( ConfiguredClassHierarchy.create( classInfoList, serviceRegistry ) );
|
||||
hierarchies.add( ConfiguredClassHierarchy.create( classInfoList, context ) );
|
||||
processedList.add( classInfoList );
|
||||
}
|
||||
}
|
||||
|
@ -107,6 +108,13 @@ public class ConfiguredClassHierarchyBuilder {
|
|||
return hierarchies;
|
||||
}
|
||||
|
||||
/**
|
||||
* Checks whether the passed jandex class info needs to be processed.
|
||||
*
|
||||
* @param info the jandex class info
|
||||
*
|
||||
* @return {@code true} if the class represented by {@code info} is relevant for the JPA mappings, {@code false} otherwise.
|
||||
*/
|
||||
private static boolean isConfiguredClass(ClassInfo info) {
|
||||
boolean isConfiguredClass = true;
|
||||
AnnotationInstance jpaEntityAnnotation = JandexHelper.getSingleAnnotation( info, JPADotNames.ENTITY );
|
||||
|
|
|
@ -0,0 +1,69 @@
|
|||
/*
|
||||
* Hibernate, Relational Persistence for Idiomatic Java
|
||||
*
|
||||
* Copyright (c) 2011, Red Hat Inc. or third-party contributors as
|
||||
* indicated by the @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.metamodel.source.annotations.entity;
|
||||
|
||||
import javax.persistence.Embeddable;
|
||||
import javax.persistence.Embedded;
|
||||
import javax.persistence.Entity;
|
||||
import javax.persistence.Id;
|
||||
|
||||
import org.junit.Test;
|
||||
|
||||
import org.hibernate.metamodel.binding.EntityBinding;
|
||||
import org.hibernate.testing.FailureExpected;
|
||||
|
||||
import static junit.framework.Assert.assertNotNull;
|
||||
|
||||
/**
|
||||
* Tests for {@code j.p.Embeddable}.
|
||||
*
|
||||
* @author Hardy Ferentschik
|
||||
*/
|
||||
public class EmbeddableBindingTests extends BaseAnnotationBindingTestCase {
|
||||
@Test
|
||||
@FailureExpected(jiraKey = "HHH6173", message = "Under construction")
|
||||
public void testEmbeddable() {
|
||||
buildMetadataSources( User.class );
|
||||
EntityBinding binding = getEntityBinding( User.class );
|
||||
assertNotNull( binding.getAttributeBinding( "address" ) );
|
||||
}
|
||||
|
||||
@Entity
|
||||
class User {
|
||||
@Id
|
||||
private int id;
|
||||
|
||||
@Embedded
|
||||
private Address address;
|
||||
}
|
||||
|
||||
@Embeddable
|
||||
class Address {
|
||||
String street;
|
||||
String city;
|
||||
String postCode;
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue