From 000b647e4349be9c4ef6e9e78c325d4ba37ab0b1 Mon Sep 17 00:00:00 2001 From: Hardy Ferentschik Date: Thu, 28 Apr 2011 18:09:34 +0200 Subject: [PATCH] HHH-6161 Working w/ domain and relational state objects --- .../binding/AbstractAttributeBinding.java | 2 +- .../metamodel/binding/CollectionElement.java | 6 +- .../binding/HibernateTypeDescriptor.java | 2 +- .../binding/SimpleAttributeBinding.java | 27 +++-- .../source/annotations/ConfiguredClass.java | 24 ++-- .../source/annotations/EntityBinder.java | 111 +++++++++++++++++- .../source/annotations/HibernateDotNames.java | 3 + .../source/annotations/JPADotNames.java | 3 + .../source/annotations/MappedProperty.java | 12 +- .../util/GenericTypeDiscoveryTest.java | 19 ++- 10 files changed, 165 insertions(+), 44 deletions(-) diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java index cee70c8932..aa2f7f2fc2 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/AbstractAttributeBinding.java @@ -77,7 +77,7 @@ public abstract class AbstractAttributeBinding implements AttributeBinding { } public void initialize(DomainState state) { - hibernateTypeDescriptor.intialize( state.getHibernateTypeDescriptor() ); + hibernateTypeDescriptor.initialize( state.getHibernateTypeDescriptor() ); attribute = state.getAttribute(); isLazy = state.isLazy(); propertyAccessorName = state.getPropertyAccessorName(); diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java index bf84c2fa6b..5c6aff76fd 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/CollectionElement.java @@ -23,11 +23,7 @@ */ package org.hibernate.metamodel.binding; -import org.dom4j.Element; - import org.hibernate.metamodel.relational.Value; -import org.hibernate.metamodel.source.hbm.HbmHelper; -import org.hibernate.metamodel.source.util.DomHelper; /** * TODO : javadoc @@ -52,7 +48,7 @@ public class CollectionElement { } public void initialize(DomainState state) { - hibernateTypeDescriptor.intialize( state.getHibernateTypeDescriptor() ); + hibernateTypeDescriptor.initialize( state.getHibernateTypeDescriptor() ); nodeName = state.getNodeName(); } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java index b4bdc4120f..4c3aca15e3 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/HibernateTypeDescriptor.java @@ -53,7 +53,7 @@ public class HibernateTypeDescriptor { this.explicitType = explicitType; } - public void intialize(HibernateTypeDescriptor hibernateTypeDescriptor) { + public void initialize(HibernateTypeDescriptor hibernateTypeDescriptor) { typeName = hibernateTypeDescriptor.typeName; explicitType = hibernateTypeDescriptor.explicitType; typeParameters = hibernateTypeDescriptor.typeParameters; diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java index 3b2cb56130..4c76cd715d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/binding/SimpleAttributeBinding.java @@ -23,7 +23,6 @@ */ package org.hibernate.metamodel.binding; -import java.util.LinkedHashSet; import java.util.Set; import org.hibernate.MappingException; @@ -35,7 +34,6 @@ import org.hibernate.metamodel.relational.SimpleValue; import org.hibernate.metamodel.relational.Size; import org.hibernate.metamodel.relational.TableSpecification; import org.hibernate.metamodel.relational.Tuple; -import org.hibernate.metamodel.relational.Value; /** * TODO : javadoc @@ -47,20 +45,34 @@ public class SimpleAttributeBinding extends SingularAttributeBinding { public PropertyGeneration getPropertyGeneration(); } - public static interface SingleValueRelationalState {} + public static interface SingleValueRelationalState { + } + public static interface ColumnRelationalState extends SingleValueRelationalState { NamingStrategy getNamingStrategy(); + String getExplicitColumnName(); + boolean isUnique(); + Size getSize(); + boolean isNullable(); + String getCheckCondition(); + String getDefault(); + String getSqlType(); + String getCustomWriteFragment(); + String getCustomReadFragment(); + String getComment(); + Set getUniqueKeys(); + Set getIndexes(); } @@ -90,7 +102,8 @@ public class SimpleAttributeBinding extends SingularAttributeBinding { private Column createColumn(ColumnRelationalState state) { final String explicitName = state.getExplicitColumnName(); - final String logicalColumnName = state.getNamingStrategy().logicalColumnName( explicitName, getAttribute().getName() ); + final String logicalColumnName = state.getNamingStrategy() + .logicalColumnName( explicitName, getAttribute().getName() ); final TableSpecification table = getEntityBinding().getBaseTable(); final String columnName = explicitName == null ? @@ -100,8 +113,8 @@ public class SimpleAttributeBinding extends SingularAttributeBinding { // mappings.addColumnBinding( logicalColumnName, column, table ); Column columnValue = table.createColumn( columnName ); columnValue.getSize().initialize( state.getSize() ); - columnValue.setNullable( ! forceNonNullable() && state.isNullable() ); - columnValue.setUnique( ! forceUnique() && state.isUnique() ); + columnValue.setNullable( !forceNonNullable() && state.isNullable() ); + columnValue.setUnique( !forceUnique() && state.isUnique() ); columnValue.setCheckCondition( state.getCheckCondition() ); columnValue.setDefaultValue( state.getDefault() ); columnValue.setSqlType( state.getSqlType() ); @@ -138,7 +151,7 @@ public class SimpleAttributeBinding extends SingularAttributeBinding { setValue( createSingleValue( state.getSingleValueRelationalStates().iterator().next() ) ); } else { - Tuple tuple = getEntityBinding().getBaseTable().createTuple( "[" + getAttribute().getName() + "]" ); + Tuple tuple = getEntityBinding().getBaseTable().createTuple( "[" + getAttribute().getName() + "]" ); for ( SingleValueRelationalState singleValueState : state.getSingleValueRelationalStates() ) { tuple.addValue( createSingleValue( singleValueState ) ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java index 9a87c6c0c6..223c3ef93b 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/ConfiguredClass.java @@ -30,7 +30,9 @@ import java.lang.reflect.Type; import java.util.ArrayList; import java.util.Collections; import java.util.HashSet; +import java.util.LinkedHashMap; import java.util.List; +import java.util.Map; import java.util.Set; import javax.persistence.AccessType; @@ -64,7 +66,7 @@ public class ConfiguredClass { private final AccessType classAccessType; private final AccessType hierarchyAccessType; private final boolean isMappedSuperClass; - private final List mappedProperties; + private final Map mappedProperties; public ConfiguredClass(ClassInfo info, ConfiguredClass parent, AccessType hierarchyAccessType, ServiceRegistry serviceRegistry, ResolvedTypeWithMembers resolvedType) { this.classInfo = info; @@ -78,10 +80,14 @@ public class ConfiguredClass { isMappedSuperClass = mappedSuperClassAnnotation != null; classAccessType = determineClassAccessType(); - List tmpProperties = collectMappedProperties( resolvedType ); + List properties = collectMappedProperties( resolvedType ); // make sure the properties are ordered by property name - Collections.sort( tmpProperties ); - mappedProperties = Collections.unmodifiableList( tmpProperties ); + Collections.sort( properties ); + Map tmpMap = new LinkedHashMap(); + for ( MappedProperty property : properties ) { + tmpMap.put( property.getName(), property ); + } + mappedProperties = Collections.unmodifiableMap( tmpMap ); } public String getName() { @@ -104,8 +110,12 @@ public class ConfiguredClass { return isMappedSuperClass; } - public List getMappedProperties() { - return mappedProperties; + public Iterable getMappedProperties() { + return mappedProperties.values(); + } + + public MappedProperty getMappedProperty(String propertyName) { + return mappedProperties.get( propertyName ); } @Override @@ -298,7 +308,7 @@ public class ConfiguredClass { resolvedMembers = resolvedType.getMemberMethods(); } Type type = findResolvedType( member.getName(), resolvedMembers ); - return new MappedProperty( name, type ); + return new MappedProperty( name, (Class) type ); } private Type findResolvedType(String name, ResolvedMember[] resolvedMembers) { diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java index a4ad5551c3..1bd2205699 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/EntityBinder.java @@ -26,11 +26,13 @@ package org.hibernate.metamodel.source.annotations; import java.util.LinkedHashSet; import java.util.List; import java.util.Map; +import java.util.Set; import org.jboss.jandex.AnnotationInstance; import org.hibernate.AssertionFailure; import org.hibernate.MappingException; +import org.hibernate.cfg.NamingStrategy; import org.hibernate.internal.util.StringHelper; import org.hibernate.mapping.PropertyGeneration; import org.hibernate.metamodel.binding.EntityBinding; @@ -39,6 +41,8 @@ import org.hibernate.metamodel.binding.SimpleAttributeBinding; import org.hibernate.metamodel.domain.Attribute; import org.hibernate.metamodel.domain.Entity; import org.hibernate.metamodel.domain.Hierarchical; +import org.hibernate.metamodel.relational.Schema; +import org.hibernate.metamodel.relational.Size; import org.hibernate.metamodel.source.annotations.util.JandexHelper; import org.hibernate.metamodel.source.internal.MetadataImpl; @@ -56,14 +60,19 @@ public class EntityBinder { this.meta = metadata; EntityBinding entityBinding = new EntityBinding(); bindJpaEntityAnnotation( entityBinding ); - // we also have to take care of an optional Hibernate specific @Id - bindHibernateEntityAnnotation( entityBinding ); + bindHibernateEntityAnnotation( entityBinding ); // optional hibernate specific @org.hibernate.annotations.Entity + bindTable( entityBinding ); + if ( configuredClass.isRoot() ) { bindId( entityBinding ); } meta.addEntity( entityBinding ); } + private void bindTable(EntityBinding entityBinding) { + final Schema schema = meta.getDatabase().getSchema( null ); + } + private void bindId(EntityBinding entityBinding) { switch ( determineIdType() ) { case SIMPLE: { @@ -106,12 +115,25 @@ public class EntityBinder { entityBinding.getEntity().getOrCreateSingularAttribute( idName ); SimpleAttributeBinding idBinding = entityBinding.makeSimplePrimaryKeyAttributeBinding( idName ); + MappedProperty idProperty = entity.getMappedProperty( idName ); AnnotationSimpleAttributeDomainState domainState = new AnnotationSimpleAttributeDomainState(); - //domainState.propertyGeneration = + HibernateTypeDescriptor typeDescriptor = new HibernateTypeDescriptor(); + typeDescriptor.setTypeName( idProperty.getType().getName() ); + domainState.typeDescriptor = typeDescriptor; + domainState.attribute = entityBinding.getEntity().getOrCreateSingularAttribute( idProperty.getName() ); idBinding.initialize( domainState ); - idBinding.initializeTupleValue( new AnnotationSimpleAttributeRelationalState() ); + + AnnotationColumnRelationalState columnRelationsState = new AnnotationColumnRelationalState(); + columnRelationsState.namingStrategy = meta.getNamingStrategy(); + columnRelationsState.columnName = idProperty.getColumnName(); + columnRelationsState.unique = true; + columnRelationsState.nullable = false; + + AnnotationSimpleAttributeRelationalState relationalState = new AnnotationSimpleAttributeRelationalState(); + relationalState.valueStates.add( columnRelationsState ); + idBinding.initializeTupleValue( relationalState ); } private void bindHibernateEntityAnnotation(EntityBinding entityBinding) { @@ -199,6 +221,8 @@ public class EntityBinder { public static class AnnotationSimpleAttributeDomainState implements SimpleAttributeBinding.DomainState { PropertyGeneration propertyGeneration; + HibernateTypeDescriptor typeDescriptor; + Attribute attribute; @Override public PropertyGeneration getPropertyGeneration() { @@ -235,12 +259,12 @@ public class EntityBinder { @Override public HibernateTypeDescriptor getHibernateTypeDescriptor() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return typeDescriptor; } @Override public Attribute getAttribute() { - return null; //To change body of implemented methods use File | Settings | File Templates. + return attribute; } @Override @@ -281,9 +305,84 @@ public class EntityBinder { public static class AnnotationSimpleAttributeRelationalState implements SimpleAttributeBinding.TupleRelationalState { + LinkedHashSet valueStates = new LinkedHashSet(); @Override public LinkedHashSet getSingleValueRelationalStates() { + return valueStates; + } + } + + public static class AnnotationColumnRelationalState + implements SimpleAttributeBinding.ColumnRelationalState { + + NamingStrategy namingStrategy; + String columnName; + boolean unique; + boolean nullable; + + @Override + public NamingStrategy getNamingStrategy() { + return namingStrategy; + } + + @Override + public String getExplicitColumnName() { + return columnName; + } + + @Override + public boolean isUnique() { + return unique; + } + + @Override + public Size getSize() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public boolean isNullable() { + return nullable; + } + + @Override + public String getCheckCondition() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getDefault() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getSqlType() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getCustomWriteFragment() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getCustomReadFragment() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public String getComment() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Set getUniqueKeys() { + return null; //To change body of implemented methods use File | Settings | File Templates. + } + + @Override + public Set getIndexes() { return null; //To change body of implemented methods use File | Settings | File Templates. } } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java index b7ab8ace0c..14674ac67d 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/HibernateDotNames.java @@ -25,6 +25,7 @@ package org.hibernate.metamodel.source.annotations; import org.jboss.jandex.DotName; +import org.hibernate.annotations.Check; import org.hibernate.annotations.Entity; import org.hibernate.annotations.FetchProfile; import org.hibernate.annotations.FetchProfiles; @@ -38,6 +39,8 @@ public interface HibernateDotNames { public static final DotName ENTITY = DotName.createSimple( Entity.class.getName() ); public static final DotName FETCH_PROFILES = DotName.createSimple( FetchProfiles.class.getName() ); public static final DotName FETCH_PROFILE = DotName.createSimple( FetchProfile.class.getName() ); + + public static final DotName CHECK = DotName.createSimple( Check.class.getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java index 9f0eb333fe..0e1b32e3d1 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/JPADotNames.java @@ -29,6 +29,7 @@ import javax.persistence.Entity; import javax.persistence.Id; import javax.persistence.Inheritance; import javax.persistence.MappedSuperclass; +import javax.persistence.Table; import javax.persistence.Transient; import org.jboss.jandex.DotName; @@ -47,6 +48,8 @@ public interface JPADotNames { public static final DotName EMBEDDED_ID = DotName.createSimple( EmbeddedId.class.getName() ); public static final DotName ACCESS = DotName.createSimple( Access.class.getName() ); public static final DotName TRANSIENT = DotName.createSimple( Transient.class.getName() ); + + public static final DotName TABLE = DotName.createSimple( Table.class.getName() ); } diff --git a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedProperty.java b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedProperty.java index 0148fa5df5..68d6f144ce 100644 --- a/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedProperty.java +++ b/hibernate-core/src/main/java/org/hibernate/metamodel/source/annotations/MappedProperty.java @@ -23,8 +23,6 @@ */ package org.hibernate.metamodel.source.annotations; -import java.lang.reflect.Type; - /** * Represent a mapped property (explicitly or implicitly mapped). * @@ -32,9 +30,9 @@ import java.lang.reflect.Type; */ public class MappedProperty implements Comparable { private final String name; - private final Type type; + private final Class type; - MappedProperty(String name, Type type) { + MappedProperty(String name, Class type) { this.name = name; this.type = type; } @@ -43,7 +41,11 @@ public class MappedProperty implements Comparable { return name; } - public Type getType() { + public String getColumnName() { + return name; + } + + public Class getType() { return type; } diff --git a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java index 63282fa48c..bb506d59c6 100644 --- a/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java +++ b/hibernate-core/src/test/java/org/hibernate/metamodel/source/annotations/util/GenericTypeDiscoveryTest.java @@ -24,7 +24,6 @@ package org.hibernate.metamodel.source.annotations.util; import java.util.Iterator; -import java.util.List; import java.util.Set; import javax.persistence.Entity; import javax.persistence.GeneratedValue; @@ -81,36 +80,32 @@ public class GenericTypeDiscoveryTest extends BaseUnitTestCase { ConfiguredClass configuredClass = iter.next(); ClassInfo info = configuredClass.getClassInfo(); assertEquals( "wrong class", DotName.createSimple( Stuff.class.getName() ), info.name() ); - List mappedProperties = configuredClass.getMappedProperties(); - assertTrue( "Stuff should have one mapped property", mappedProperties.size() == 1 ); - MappedProperty property = mappedProperties.get( 0 ); + MappedProperty property = configuredClass.getMappedProperty( "value" ); assertEquals( Price.class, property.getType() ); assertTrue( iter.hasNext() ); configuredClass = iter.next(); info = configuredClass.getClassInfo(); assertEquals( "wrong class", DotName.createSimple( PricedStuff.class.getName() ), info.name() ); - mappedProperties = configuredClass.getMappedProperties(); - assertTrue( "PricedStuff should not mapped properties", mappedProperties.size() == 0 ); + assertFalse( + "PricedStuff should not mapped properties", configuredClass.getMappedProperties().iterator().hasNext() + ); assertTrue( iter.hasNext() ); configuredClass = iter.next(); info = configuredClass.getClassInfo(); assertEquals( "wrong class", DotName.createSimple( Item.class.getName() ), info.name() ); - mappedProperties = configuredClass.getMappedProperties(); - assertTrue( "Item should have 4 mapped properties", mappedProperties.size() == 4 ); // properties are alphabetically ordered! - property = mappedProperties.get( 2 ); + property = configuredClass.getMappedProperty( "owner" ); assertEquals( SomeGuy.class, property.getType() ); - property = mappedProperties.get( 3 ); + property = configuredClass.getMappedProperty( "type" ); assertEquals( PaperType.class, property.getType() ); assertTrue( iter.hasNext() ); configuredClass = iter.next(); info = configuredClass.getClassInfo(); assertEquals( "wrong class", DotName.createSimple( Paper.class.getName() ), info.name() ); - mappedProperties = configuredClass.getMappedProperties(); - assertTrue( "Paper should not mapped properties", mappedProperties.size() == 0 ); + assertFalse( "Paper should not mapped properties", configuredClass.getMappedProperties().iterator().hasNext() ); assertFalse( iter.hasNext() ); }