HHH-6498 HHH-6337 : Updates to support single-table inheritance using new metamodel
This commit is contained in:
parent
2faeb783a4
commit
dc7feab061
|
@ -83,6 +83,7 @@ import org.hibernate.context.internal.ManagedSessionContext;
|
||||||
import org.hibernate.context.internal.ThreadLocalSessionContext;
|
import org.hibernate.context.internal.ThreadLocalSessionContext;
|
||||||
import org.hibernate.context.spi.CurrentSessionContext;
|
import org.hibernate.context.spi.CurrentSessionContext;
|
||||||
import org.hibernate.dialect.Dialect;
|
import org.hibernate.dialect.Dialect;
|
||||||
|
import org.hibernate.dialect.function.SQLFunction;
|
||||||
import org.hibernate.dialect.function.SQLFunctionRegistry;
|
import org.hibernate.dialect.function.SQLFunctionRegistry;
|
||||||
import org.hibernate.engine.ResultSetMappingDefinition;
|
import org.hibernate.engine.ResultSetMappingDefinition;
|
||||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
|
@ -187,8 +188,8 @@ public final class SessionFactoryImpl
|
||||||
private final transient Map<String, FetchProfile> fetchProfiles;
|
private final transient Map<String, FetchProfile> fetchProfiles;
|
||||||
private final transient Map<String,String> imports;
|
private final transient Map<String,String> imports;
|
||||||
private final transient SessionFactoryServiceRegistry serviceRegistry;
|
private final transient SessionFactoryServiceRegistry serviceRegistry;
|
||||||
private final transient JdbcServices jdbcServices;
|
private final transient JdbcServices jdbcServices;
|
||||||
private final transient Dialect dialect;
|
private final transient Dialect dialect;
|
||||||
private final transient Settings settings;
|
private final transient Settings settings;
|
||||||
private final transient Properties properties;
|
private final transient Properties properties;
|
||||||
private transient SchemaExport schemaExport;
|
private transient SchemaExport schemaExport;
|
||||||
|
@ -530,9 +531,6 @@ public final class SessionFactoryImpl
|
||||||
SessionFactoryObserver observer) throws HibernateException {
|
SessionFactoryObserver observer) throws HibernateException {
|
||||||
LOG.debug( "Building session factory" );
|
LOG.debug( "Building session factory" );
|
||||||
|
|
||||||
// TODO: remove initialization of final variables; just setting to null to make compiler happy
|
|
||||||
this.sqlFunctionRegistry = null;
|
|
||||||
|
|
||||||
this.sessionFactoryOptions = sessionFactoryOptions;
|
this.sessionFactoryOptions = sessionFactoryOptions;
|
||||||
|
|
||||||
this.properties = createPropertiesFromMap(
|
this.properties = createPropertiesFromMap(
|
||||||
|
@ -553,6 +551,10 @@ public final class SessionFactoryImpl
|
||||||
this.jdbcServices = this.serviceRegistry.getService( JdbcServices.class );
|
this.jdbcServices = this.serviceRegistry.getService( JdbcServices.class );
|
||||||
this.dialect = this.jdbcServices.getDialect();
|
this.dialect = this.jdbcServices.getDialect();
|
||||||
|
|
||||||
|
// TODO: get SQL functions from JdbcServices (HHH-6559)
|
||||||
|
//this.sqlFunctionRegistry = new SQLFunctionRegistry( this.jdbcServices.getSqlFunctions() );
|
||||||
|
this.sqlFunctionRegistry = new SQLFunctionRegistry( this.dialect, new HashMap<String, SQLFunction>() );
|
||||||
|
|
||||||
// TODO: get SQL functions from a new service
|
// TODO: get SQL functions from a new service
|
||||||
// this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), cfg.getSqlFunctions() );
|
// this.sqlFunctionRegistry = new SQLFunctionRegistry( getDialect(), cfg.getSqlFunctions() );
|
||||||
|
|
||||||
|
|
|
@ -53,6 +53,9 @@ import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
* @author Gail Badner
|
* @author Gail Badner
|
||||||
*/
|
*/
|
||||||
public class EntityBinding implements AttributeBindingContainer {
|
public class EntityBinding implements AttributeBindingContainer {
|
||||||
|
private static final String NULL_DISCRIMINATOR_MATCH_VALUE = "null";
|
||||||
|
private static final String NOT_NULL_DISCRIMINATOR_MATCH_VALUE = "not null";
|
||||||
|
|
||||||
private final EntityBinding superEntityBinding;
|
private final EntityBinding superEntityBinding;
|
||||||
private final List<EntityBinding> subEntityBindings = new ArrayList<EntityBinding>();
|
private final List<EntityBinding> subEntityBindings = new ArrayList<EntityBinding>();
|
||||||
private final HierarchyDetails hierarchyDetails;
|
private final HierarchyDetails hierarchyDetails;
|
||||||
|
@ -142,28 +145,70 @@ public class EntityBinding implements AttributeBindingContainer {
|
||||||
return subEntityBindings.size() > 0;
|
return subEntityBindings.size() > 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
public int getSubEntityBindingSpan() {
|
public int getSubEntityBindingClosureSpan() {
|
||||||
int n = subEntityBindings.size();
|
int n = subEntityBindings.size();
|
||||||
for ( EntityBinding subEntityBinding : subEntityBindings ) {
|
for ( EntityBinding subEntityBinding : subEntityBindings ) {
|
||||||
n += subEntityBinding.getSubEntityBindingSpan();
|
n += subEntityBinding.getSubEntityBindingClosureSpan();
|
||||||
}
|
}
|
||||||
return n;
|
return n;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* used for testing */
|
||||||
|
public Iterable<EntityBinding> getDirectSubEntityBindings() {
|
||||||
|
return subEntityBindings;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Iterate over subclasses in a special 'order', most derived subclasses
|
* Returns sub-EntityBinding objects in a special 'order', most derived subclasses
|
||||||
* first.
|
* first. Specifically, the sub-entity bindings follow a depth-first,
|
||||||
|
* post-order traversal
|
||||||
|
*
|
||||||
|
* Note that the returned value excludes this entity binding.
|
||||||
|
*
|
||||||
* @return sub-entity bindings ordered by those entity bindings that are most derived.
|
* @return sub-entity bindings ordered by those entity bindings that are most derived.
|
||||||
*/
|
*/
|
||||||
public Iterable<EntityBinding> getSubEntityBindingClosure() {
|
public Iterable<EntityBinding> getPostOrderSubEntityBindingClosure() {
|
||||||
List<Iterable<EntityBinding>> subclassIterables =
|
// TODO: why this order?
|
||||||
new ArrayList<Iterable<EntityBinding>>( subEntityBindings.size() + 1 );
|
List<Iterable<EntityBinding>> subclassIterables = new ArrayList<Iterable<EntityBinding>>( subEntityBindings.size() + 1 );
|
||||||
for ( EntityBinding subEntityBinding : subEntityBindings ) {
|
for ( EntityBinding subEntityBinding : subEntityBindings ) {
|
||||||
subclassIterables.add( subEntityBinding.getSubEntityBindingClosure() );
|
Iterable<EntityBinding> subSubEntityBindings = subEntityBinding.getPostOrderSubEntityBindingClosure();
|
||||||
|
if ( subSubEntityBindings.iterator().hasNext() ) {
|
||||||
|
subclassIterables.add( subSubEntityBindings );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( ! subEntityBindings.isEmpty() ) {
|
||||||
|
subclassIterables.add( subEntityBindings );
|
||||||
}
|
}
|
||||||
subclassIterables.add( subEntityBindings );
|
|
||||||
return new JoinedIterable<EntityBinding>( subclassIterables );
|
return new JoinedIterable<EntityBinding>( subclassIterables );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns sub-EntityBinding ordered as a depth-first,
|
||||||
|
* pre-order traversal (a subclass precedes its own subclasses).
|
||||||
|
*
|
||||||
|
* Note that the returned value specifically excludes this entity binding.
|
||||||
|
*
|
||||||
|
* @return sub-entity bindings ordered as a depth-first,
|
||||||
|
* pre-order traversal
|
||||||
|
*/
|
||||||
|
public Iterable<EntityBinding> getPreOrderSubEntityBindingClosure() {
|
||||||
|
return getPreOrderSubEntityBindingClosure( false );
|
||||||
|
}
|
||||||
|
|
||||||
|
private Iterable<EntityBinding> getPreOrderSubEntityBindingClosure(boolean includeThis) {
|
||||||
|
List<Iterable<EntityBinding>> iterables = new ArrayList<Iterable<EntityBinding>>();
|
||||||
|
if ( includeThis ) {
|
||||||
|
iterables.add( java.util.Collections.singletonList( this ) );
|
||||||
|
}
|
||||||
|
for ( EntityBinding subEntityBinding : subEntityBindings ) {
|
||||||
|
Iterable<EntityBinding> subSubEntityBindingClosure = subEntityBinding.getPreOrderSubEntityBindingClosure( true );
|
||||||
|
if ( subSubEntityBindingClosure.iterator().hasNext() ) {
|
||||||
|
iterables.add( subSubEntityBindingClosure );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return new JoinedIterable<EntityBinding>( iterables );
|
||||||
|
}
|
||||||
|
|
||||||
public Entity getEntity() {
|
public Entity getEntity() {
|
||||||
return entity;
|
return entity;
|
||||||
}
|
}
|
||||||
|
@ -212,6 +257,14 @@ public class EntityBinding implements AttributeBindingContainer {
|
||||||
return getHierarchyDetails().getVersioningAttributeBinding() != null;
|
return getHierarchyDetails().getVersioningAttributeBinding() != null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isDiscriminatorMatchValueNull() {
|
||||||
|
return NULL_DISCRIMINATOR_MATCH_VALUE.equals( discriminatorMatchValue );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isDiscriminatorMatchValueNotNull() {
|
||||||
|
return NOT_NULL_DISCRIMINATOR_MATCH_VALUE.equals( discriminatorMatchValue );
|
||||||
|
}
|
||||||
|
|
||||||
public String getDiscriminatorMatchValue() {
|
public String getDiscriminatorMatchValue() {
|
||||||
return discriminatorMatchValue;
|
return discriminatorMatchValue;
|
||||||
}
|
}
|
||||||
|
@ -521,4 +574,21 @@ public class EntityBinding implements AttributeBindingContainer {
|
||||||
}
|
}
|
||||||
return iterable;
|
return iterable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the attribute bindings for this EntityBinding and all of its
|
||||||
|
* sub-EntityBinding, starting from the root of the hierarchy; includes
|
||||||
|
* the identifier and attribute bindings defined as part of a join.
|
||||||
|
* @return
|
||||||
|
*/
|
||||||
|
public Iterable<AttributeBinding> getSubEntityAttributeBindingClosure() {
|
||||||
|
List<Iterable<AttributeBinding>> iterables = new ArrayList<Iterable<AttributeBinding>>();
|
||||||
|
iterables.add( getAttributeBindingClosure() );
|
||||||
|
for ( EntityBinding subEntityBinding : getPreOrderSubEntityBindingClosure() ) {
|
||||||
|
// only add attribute bindings declared for the subEntityBinding
|
||||||
|
iterables.add( subEntityBinding.attributeBindings() );
|
||||||
|
// TODO: if EntityBinding.attributeBindings() excludes joined attributes, then they need to be added here
|
||||||
|
}
|
||||||
|
return new JoinedIterable<AttributeBinding>( iterables );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -768,7 +768,6 @@ public abstract class AbstractEntityPersister
|
||||||
final EntityBinding entityBinding,
|
final EntityBinding entityBinding,
|
||||||
final EntityRegionAccessStrategy cacheAccessStrategy,
|
final EntityRegionAccessStrategy cacheAccessStrategy,
|
||||||
final SessionFactoryImplementor factory) throws HibernateException {
|
final SessionFactoryImplementor factory) throws HibernateException {
|
||||||
// TODO: Implement! Initializing final fields to make compiler happy
|
|
||||||
this.factory = factory;
|
this.factory = factory;
|
||||||
this.cacheAccessStrategy = cacheAccessStrategy;
|
this.cacheAccessStrategy = cacheAccessStrategy;
|
||||||
this.isLazyPropertiesCacheable =
|
this.isLazyPropertiesCacheable =
|
||||||
|
@ -812,8 +811,6 @@ public abstract class AbstractEntityPersister
|
||||||
rootTableKeyColumnReaders[i] = col.getReadFragment();
|
rootTableKeyColumnReaders[i] = col.getReadFragment();
|
||||||
rootTableKeyColumnReaderTemplates[i] = getTemplateFromString( col.getReadFragment(), factory );
|
rootTableKeyColumnReaderTemplates[i] = getTemplateFromString( col.getReadFragment(), factory );
|
||||||
}
|
}
|
||||||
// TODO: Fix when HHH-6337 is fixed; for now assume entityBinding is the root
|
|
||||||
// identifierAliases[i] = col.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getPrimaryTable() );
|
|
||||||
identifierAliases[i] = col.getAlias( factory.getDialect() );
|
identifierAliases[i] = col.getAlias( factory.getDialect() );
|
||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
@ -915,8 +912,8 @@ public abstract class AbstractEntityPersister
|
||||||
propertyColumnWriters[i] = colWriters;
|
propertyColumnWriters[i] = colWriters;
|
||||||
propertyColumnAliases[i] = colAliases;
|
propertyColumnAliases[i] = colAliases;
|
||||||
|
|
||||||
propertyColumnUpdateable[i] = propertyColumnInsertability;
|
propertyColumnUpdateable[i] = propertyColumnUpdatability;
|
||||||
propertyColumnInsertable[i] = propertyColumnUpdatability;
|
propertyColumnInsertable[i] = propertyColumnInsertability;
|
||||||
|
|
||||||
if ( lazyAvailable && singularAttributeBinding.isLazy() ) {
|
if ( lazyAvailable && singularAttributeBinding.isLazy() ) {
|
||||||
lazyProperties.add( singularAttributeBinding.getAttribute().getName() );
|
lazyProperties.add( singularAttributeBinding.getAttribute().getName() );
|
||||||
|
@ -967,9 +964,7 @@ public abstract class AbstractEntityPersister
|
||||||
List<Boolean> columnSelectables = new ArrayList<Boolean>();
|
List<Boolean> columnSelectables = new ArrayList<Boolean>();
|
||||||
List<Boolean> propNullables = new ArrayList<Boolean>();
|
List<Boolean> propNullables = new ArrayList<Boolean>();
|
||||||
|
|
||||||
// TODO: fix this when EntityBinding.getSubclassAttributeBindingClosure() is working
|
for ( AttributeBinding attributeBinding : entityBinding.getSubEntityAttributeBindingClosure() ) {
|
||||||
// for ( AttributeBinding prop : entityBinding.getSubclassAttributeBindingClosure() ) {
|
|
||||||
for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
|
|
||||||
if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) {
|
if ( attributeBinding == entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) {
|
||||||
// entity identifier is not considered a "normal" property
|
// entity identifier is not considered a "normal" property
|
||||||
continue;
|
continue;
|
||||||
|
|
|
@ -466,8 +466,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
isNullableTable = new boolean[joinSpan];
|
isNullableTable = new boolean[joinSpan];
|
||||||
keyColumnNames = new String[joinSpan][];
|
keyColumnNames = new String[joinSpan][];
|
||||||
|
|
||||||
// TODO: fix when EntityBinhding.getRootEntityBinding() exists (HHH-6337)
|
|
||||||
//final Table table = entityBinding.getRootEntityBinding().getPrimaryTable();
|
|
||||||
final TableSpecification table = entityBinding.getPrimaryTable();
|
final TableSpecification table = entityBinding.getPrimaryTable();
|
||||||
qualifiedTableNames[0] = table.getQualifiedName( factory.getDialect() );
|
qualifiedTableNames[0] = table.getQualifiedName( factory.getDialect() );
|
||||||
isInverseTable[0] = false;
|
isInverseTable[0] = false;
|
||||||
|
@ -538,15 +536,8 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
|
|
||||||
// DISCRIMINATOR
|
// DISCRIMINATOR
|
||||||
|
|
||||||
// TODO: fix this when can get subclass info from EntityBinding (HHH-6337)
|
|
||||||
// for now set hasSubclasses to false
|
|
||||||
//hasSubclasses = entityBinding.hasSubclasses();
|
|
||||||
boolean hasSubclasses = false;
|
|
||||||
|
|
||||||
//polymorphic = ! entityBinding.isRoot() || entityBinding.hasSubclasses();
|
|
||||||
boolean isPolymorphic = ! entityBinding.isRoot() || hasSubclasses;
|
|
||||||
final Object discriminatorValue;
|
final Object discriminatorValue;
|
||||||
if ( isPolymorphic ) {
|
if ( entityBinding.isPolymorphic() ) {
|
||||||
SimpleValue discriminatorRelationalValue = entityBinding.getHierarchyDetails().getEntityDiscriminator().getBoundValue();
|
SimpleValue discriminatorRelationalValue = entityBinding.getHierarchyDetails().getEntityDiscriminator().getBoundValue();
|
||||||
if ( discriminatorRelationalValue == null ) {
|
if ( discriminatorRelationalValue == null ) {
|
||||||
throw new MappingException("discriminator mapping required for single table polymorphic persistence");
|
throw new MappingException("discriminator mapping required for single table polymorphic persistence");
|
||||||
|
@ -569,9 +560,6 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
column.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ) :
|
column.getColumnName().encloseInQuotesIfQuoted( factory.getDialect() ) :
|
||||||
column.getReadFragment();
|
column.getReadFragment();
|
||||||
discriminatorColumnReaderTemplate = getTemplateFromColumn( column, factory );
|
discriminatorColumnReaderTemplate = getTemplateFromColumn( column, factory );
|
||||||
// TODO: fix this when EntityBinding.getRootEntityBinding() is implemented;
|
|
||||||
// for now, assume entityBinding is the root
|
|
||||||
//discriminatorAlias = column.getAlias( factory.getDialect(), entityBinding.getRootEntityBinding().getPrimaryTable );
|
|
||||||
discriminatorAlias = column.getAlias( factory.getDialect() );
|
discriminatorAlias = column.getAlias( factory.getDialect() );
|
||||||
discriminatorFormula = null;
|
discriminatorFormula = null;
|
||||||
discriminatorFormulaTemplate = null;
|
discriminatorFormulaTemplate = null;
|
||||||
|
@ -648,9 +636,7 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
ArrayList formulaJoinedNumbers = new ArrayList();
|
ArrayList formulaJoinedNumbers = new ArrayList();
|
||||||
ArrayList propertyJoinNumbers = new ArrayList();
|
ArrayList propertyJoinNumbers = new ArrayList();
|
||||||
|
|
||||||
// TODO: fix when subclasses are working (HHH-6337)
|
for ( AttributeBinding attributeBinding : entityBinding.getSubEntityAttributeBindingClosure() ) {
|
||||||
//for ( AttributeBinding prop : entityBinding.getSubclassAttributeBindingClosure() ) {
|
|
||||||
for ( AttributeBinding attributeBinding : entityBinding.getAttributeBindingClosure() ) {
|
|
||||||
if ( ! attributeBinding.getAttribute().isSingular() ) {
|
if ( ! attributeBinding.getAttribute().isSingular() ) {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -680,18 +666,41 @@ public class SingleTableEntityPersister extends AbstractEntityPersister {
|
||||||
subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers);
|
subclassFormulaTableNumberClosure = ArrayHelper.toIntArray(formulaJoinedNumbers);
|
||||||
subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers);
|
subclassPropertyTableNumberClosure = ArrayHelper.toIntArray(propertyJoinNumbers);
|
||||||
|
|
||||||
// TODO; fix when subclasses are working (HHH-6337)
|
int subclassSpan = entityBinding.getSubEntityBindingClosureSpan() + 1;
|
||||||
//int subclassSpan = entityBinding.getSubclassSpan() + 1;
|
|
||||||
int subclassSpan = 1;
|
|
||||||
subclassClosure = new String[subclassSpan];
|
subclassClosure = new String[subclassSpan];
|
||||||
subclassClosure[0] = getEntityName();
|
subclassClosure[0] = getEntityName();
|
||||||
if ( isPolymorphic ) {
|
if ( entityBinding.isPolymorphic() ) {
|
||||||
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
|
subclassesByDiscriminatorValue.put( discriminatorValue, getEntityName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
// SUBCLASSES
|
// SUBCLASSES
|
||||||
|
if ( entityBinding.isPolymorphic() ) {
|
||||||
// TODO; fix when subclasses are working (HHH-6337)
|
int k=1;
|
||||||
|
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
|
||||||
|
subclassClosure[k++] = subEntityBinding.getEntity().getName();
|
||||||
|
if ( subEntityBinding.isDiscriminatorMatchValueNull() ) {
|
||||||
|
subclassesByDiscriminatorValue.put( NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
|
||||||
|
}
|
||||||
|
else if ( subEntityBinding.isDiscriminatorMatchValueNotNull() ) {
|
||||||
|
subclassesByDiscriminatorValue.put( NOT_NULL_DISCRIMINATOR, subEntityBinding.getEntity().getName() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
try {
|
||||||
|
DiscriminatorType dtype = (DiscriminatorType) discriminatorType;
|
||||||
|
subclassesByDiscriminatorValue.put(
|
||||||
|
dtype.stringToObject( subEntityBinding.getDiscriminatorMatchValue() ),
|
||||||
|
subEntityBinding.getEntity().getName()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
catch (ClassCastException cce) {
|
||||||
|
throw new MappingException("Illegal discriminator type: " + discriminatorType.getName() );
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
throw new MappingException("Error parsing discriminator value", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
initLockers();
|
initLockers();
|
||||||
|
|
||||||
|
|
|
@ -29,6 +29,7 @@ import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
import org.hibernate.metamodel.binding.EntityBinding;
|
import org.hibernate.metamodel.binding.EntityBinding;
|
||||||
|
|
||||||
|
@ -58,14 +59,9 @@ public class DynamicMapInstantiator implements Instantiator {
|
||||||
public DynamicMapInstantiator(EntityBinding mappingInfo) {
|
public DynamicMapInstantiator(EntityBinding mappingInfo) {
|
||||||
this.entityName = mappingInfo.getEntity().getName();
|
this.entityName = mappingInfo.getEntity().getName();
|
||||||
isInstanceEntityNames.add( entityName );
|
isInstanceEntityNames.add( entityName );
|
||||||
// TODO: fix this when can get subclass info from EntityBinding (HHH-6337)
|
for ( EntityBinding subEntityBinding : mappingInfo.getPostOrderSubEntityBindingClosure() ) {
|
||||||
//if ( mappingInfo.hasSubclasses() ) {
|
isInstanceEntityNames.add( subEntityBinding.getEntity().getName() );
|
||||||
// Iterator itr = mappingInfo.getSubclassClosureIterator();
|
}
|
||||||
// while ( itr.hasNext() ) {
|
|
||||||
// final PersistentClass subclassInfo = ( PersistentClass ) itr.next();
|
|
||||||
// isInstanceEntityNames.add( subclassInfo.getEntityName() );
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public final Object instantiate(Serializable id) {
|
public final Object instantiate(Serializable id) {
|
||||||
|
|
|
@ -360,9 +360,7 @@ public class EntityMetamodel implements Serializable {
|
||||||
|
|
||||||
name = entityBinding.getEntity().getName();
|
name = entityBinding.getEntity().getName();
|
||||||
|
|
||||||
// TODO: Fix after HHH-6337 is fixed; for now assume entityBinding is the root binding
|
rootName = entityBinding.getHierarchyDetails().getRootEntityBinding().getEntity().getName();
|
||||||
//rootName = entityBinding.getRootEntityBinding().getName();
|
|
||||||
rootName = name;
|
|
||||||
entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name );
|
entityType = sessionFactory.getTypeResolver().getTypeFactory().manyToOne( name );
|
||||||
|
|
||||||
identifierProperty = PropertyFactory.buildIdentifierProperty(
|
identifierProperty = PropertyFactory.buildIdentifierProperty(
|
||||||
|
@ -386,7 +384,6 @@ public class EntityMetamodel implements Serializable {
|
||||||
boolean hasLazy = false;
|
boolean hasLazy = false;
|
||||||
|
|
||||||
// TODO: Fix after HHH-6337 is fixed; for now assume entityBinding is the root binding
|
// TODO: Fix after HHH-6337 is fixed; for now assume entityBinding is the root binding
|
||||||
//BasicAttributeBinding rootEntityIdentifier = entityBinding.getRootEntityBinding().getEntityIdentifier().getValueBinding();
|
|
||||||
BasicAttributeBinding rootEntityIdentifier = entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding();
|
BasicAttributeBinding rootEntityIdentifier = entityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding();
|
||||||
// entityBinding.getAttributeClosureSpan() includes the identifier binding;
|
// entityBinding.getAttributeClosureSpan() includes the identifier binding;
|
||||||
// "properties" here excludes the ID, so subtract 1 if the identifier binding is non-null
|
// "properties" here excludes the ID, so subtract 1 if the identifier binding is non-null
|
||||||
|
@ -540,13 +537,8 @@ public class EntityMetamodel implements Serializable {
|
||||||
dynamicUpdate = entityBinding.isDynamicUpdate();
|
dynamicUpdate = entityBinding.isDynamicUpdate();
|
||||||
dynamicInsert = entityBinding.isDynamicInsert();
|
dynamicInsert = entityBinding.isDynamicInsert();
|
||||||
|
|
||||||
// TODO: fix this when can get subclass info from EntityBinding (HHH-6337)
|
hasSubclasses = entityBinding.hasSubEntityBindings();
|
||||||
// for now set hasSubclasses to false
|
polymorphic = entityBinding.isPolymorphic();
|
||||||
//hasSubclasses = entityBinding.hasSubclasses();
|
|
||||||
hasSubclasses = false;
|
|
||||||
|
|
||||||
//polymorphic = ! entityBinding.isRoot() || entityBinding.hasSubclasses();
|
|
||||||
polymorphic = ! entityBinding.isRoot() || hasSubclasses;
|
|
||||||
|
|
||||||
explicitPolymorphism = entityBinding.getHierarchyDetails().isExplicitPolymorphism();
|
explicitPolymorphism = entityBinding.getHierarchyDetails().isExplicitPolymorphism();
|
||||||
inherited = ! entityBinding.isRoot();
|
inherited = ! entityBinding.isRoot();
|
||||||
|
@ -568,24 +560,17 @@ public class EntityMetamodel implements Serializable {
|
||||||
hasCollections = foundCollection;
|
hasCollections = foundCollection;
|
||||||
hasMutableProperties = foundMutable;
|
hasMutableProperties = foundMutable;
|
||||||
|
|
||||||
// TODO: fix this when can get subclass info from EntityBinding (HHH-6337)
|
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
|
||||||
// TODO: uncomment when it's possible to get subclasses from an EntityBinding
|
subclassEntityNames.add( subEntityBinding.getEntity().getName() );
|
||||||
//iter = entityBinding.getSubclassIterator();
|
if ( subEntityBinding.getEntity().getClassReference() != null ) {
|
||||||
//while ( iter.hasNext() ) {
|
entityNameByInheritenceClassMap.put(
|
||||||
// subclassEntityNames.add( ( (PersistentClass) iter.next() ).getEntityName() );
|
subEntityBinding.getEntity().getClassReference(),
|
||||||
//}
|
subEntityBinding.getEntity().getName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
subclassEntityNames.add( name );
|
subclassEntityNames.add( name );
|
||||||
|
|
||||||
if ( mappedClass != null ) {
|
if ( mappedClass != null ) {
|
||||||
entityNameByInheritenceClassMap.put( mappedClass, name );
|
entityNameByInheritenceClassMap.put( mappedClass, name );
|
||||||
// TODO: uncomment when it's possible to get subclasses from an EntityBinding
|
|
||||||
// iter = entityBinding.getSubclassIterator();
|
|
||||||
// while ( iter.hasNext() ) {
|
|
||||||
// final EntityBinding subclassEntityBinding = ( EntityBinding ) iter.next();
|
|
||||||
// entityNameByInheritenceClassMap.put(
|
|
||||||
// subclassEntityBinding.getEntity().getPojoEntitySpecifics().getEntityClass(),
|
|
||||||
// subclassEntityBinding.getEntity().getName() );
|
|
||||||
// }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
entityMode = hasPojoRepresentation ? EntityMode.POJO : EntityMode.MAP;
|
entityMode = hasPojoRepresentation ? EntityMode.POJO : EntityMode.MAP;
|
||||||
|
|
|
@ -278,21 +278,18 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
proxyInterfaces.add( mappedClass );
|
proxyInterfaces.add( mappedClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: fix when it's possible to get subclasses from an EntityBinding
|
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
|
||||||
//Iterator subclasses = entityBinding.getSubclassIterator();
|
final Class subclassProxy = subEntityBinding.getProxyInterfaceType().getValue();
|
||||||
//while ( subclasses.hasNext() ) {
|
final Class subclassClass = subEntityBinding.getClassReference();
|
||||||
// final Subclass subclass = ( Subclass ) subclasses.next();
|
if ( subclassProxy!=null && !subclassClass.equals( subclassProxy ) ) {
|
||||||
// final Class subclassProxy = subclass.getProxyInterface();
|
if ( ! subclassProxy.isInterface() ) {
|
||||||
// final Class subclassClass = subclass.getMappedClass();
|
throw new MappingException(
|
||||||
// if ( subclassProxy!=null && !subclassClass.equals( subclassProxy ) ) {
|
"proxy must be either an interface, or the class itself: " + subEntityBinding.getEntity().getName()
|
||||||
// if ( !subclassProxy.isInterface() ) {
|
);
|
||||||
// throw new MappingException(
|
}
|
||||||
// "proxy must be either an interface, or the class itself: " + subclass.getEntityName()
|
proxyInterfaces.add( subclassProxy );
|
||||||
// );
|
}
|
||||||
// }
|
}
|
||||||
// proxyInterfaces.add( subclassProxy );
|
|
||||||
// }
|
|
||||||
//}
|
|
||||||
|
|
||||||
for ( AttributeBinding property : entityBinding.attributeBindings() ) {
|
for ( AttributeBinding property : entityBinding.attributeBindings() ) {
|
||||||
Method method = getGetter( property ).getMethod();
|
Method method = getGetter( property ).getMethod();
|
||||||
|
|
|
@ -23,8 +23,10 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.metamodel.source.annotations.entity;
|
package org.hibernate.metamodel.source.annotations.entity;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.List;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import javax.persistence.DiscriminatorColumn;
|
import javax.persistence.DiscriminatorColumn;
|
||||||
import javax.persistence.DiscriminatorType;
|
import javax.persistence.DiscriminatorType;
|
||||||
|
@ -121,14 +123,31 @@ public class InheritanceBindingTest extends BaseAnnotationBindingTestCase {
|
||||||
assertSame( noInheritanceEntityBinding, getRootEntityBinding( SingleEntity.class ) );
|
assertSame( noInheritanceEntityBinding, getRootEntityBinding( SingleEntity.class ) );
|
||||||
assertFalse( noInheritanceEntityBinding.isPolymorphic() );
|
assertFalse( noInheritanceEntityBinding.isPolymorphic() );
|
||||||
assertFalse( noInheritanceEntityBinding.hasSubEntityBindings() );
|
assertFalse( noInheritanceEntityBinding.hasSubEntityBindings() );
|
||||||
assertEquals( 0, noInheritanceEntityBinding.getSubEntityBindingSpan() );
|
assertEquals( 0, noInheritanceEntityBinding.getSubEntityBindingClosureSpan() );
|
||||||
assertFalse( noInheritanceEntityBinding.getSubEntityBindingClosure().iterator().hasNext() );
|
assertFalse( noInheritanceEntityBinding.getPostOrderSubEntityBindingClosure().iterator().hasNext() );
|
||||||
assertEquals( 1, noInheritanceEntityBinding.getAttributeBindingClosureSpan() );
|
assertFalse( noInheritanceEntityBinding.getPreOrderSubEntityBindingClosure().iterator().hasNext() );
|
||||||
for ( AttributeBinding attributeBinding : noInheritanceEntityBinding.getAttributeBindingClosure() ) {
|
Set<AttributeBinding> directAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
if ( attributeBinding == noInheritanceEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding() ) {
|
for ( AttributeBinding attributeBinding : noInheritanceEntityBinding.attributeBindings() ) {
|
||||||
continue;
|
assertTrue( directAttributeBindings.add( attributeBinding ) );
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
assertEquals( 1, directAttributeBindings.size() );
|
||||||
|
assertSame(
|
||||||
|
noInheritanceEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding(),
|
||||||
|
directAttributeBindings.iterator().next()
|
||||||
|
);
|
||||||
|
assertEquals( 1, noInheritanceEntityBinding.getAttributeBindingClosureSpan() );
|
||||||
|
Iterator<AttributeBinding> iterator = noInheritanceEntityBinding.attributeBindings().iterator();
|
||||||
|
assertTrue( iterator.hasNext() );
|
||||||
|
assertSame( noInheritanceEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding(), iterator.next() );
|
||||||
|
assertFalse( iterator.hasNext() );
|
||||||
|
iterator = noInheritanceEntityBinding.getAttributeBindingClosure().iterator();
|
||||||
|
assertTrue( iterator.hasNext() );
|
||||||
|
assertSame( noInheritanceEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding(), iterator.next() );
|
||||||
|
assertFalse( iterator.hasNext() );
|
||||||
|
iterator = noInheritanceEntityBinding.getSubEntityAttributeBindingClosure().iterator();
|
||||||
|
assertTrue( iterator.hasNext() );
|
||||||
|
assertSame( noInheritanceEntityBinding.getHierarchyDetails().getEntityIdentifier().getValueBinding(), iterator.next() );
|
||||||
|
assertFalse( iterator.hasNext() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -151,22 +170,110 @@ public class InheritanceBindingTest extends BaseAnnotationBindingTestCase {
|
||||||
assertSame( rootEntityBinding, getRootEntityBinding( RootOfSingleTableInheritance.class ) );
|
assertSame( rootEntityBinding, getRootEntityBinding( RootOfSingleTableInheritance.class ) );
|
||||||
assertTrue( rootEntityBinding.isPolymorphic() );
|
assertTrue( rootEntityBinding.isPolymorphic() );
|
||||||
assertTrue( rootEntityBinding.hasSubEntityBindings() );
|
assertTrue( rootEntityBinding.hasSubEntityBindings() );
|
||||||
assertEquals( 3, rootEntityBinding.getSubEntityBindingSpan() );
|
Iterator<EntityBinding> directEntityBindingIterator = rootEntityBinding.getDirectSubEntityBindings().iterator();
|
||||||
Set<EntityBinding> subEntityBindings = new HashSet<EntityBinding>( );
|
assertTrue( directEntityBindingIterator.hasNext() );
|
||||||
for ( EntityBinding subEntityBinding : rootEntityBinding.getSubEntityBindingClosure() ) {
|
EntityBinding directSubEntityBinding1 = directEntityBindingIterator.next();
|
||||||
subEntityBindings.add( subEntityBinding );
|
assertTrue( directEntityBindingIterator.hasNext() );
|
||||||
|
EntityBinding directSubEntityBinding2 = directEntityBindingIterator.next();
|
||||||
|
assertFalse( directEntityBindingIterator.hasNext() );
|
||||||
|
boolean isSubclassEntityBindingFirst = directSubEntityBinding1 == subclassEntityBinding;
|
||||||
|
if ( isSubclassEntityBindingFirst ) {
|
||||||
|
assertSame( otherSubclassEntityBinding, directSubEntityBinding2 );
|
||||||
}
|
}
|
||||||
assertEquals( 3, subEntityBindings.size() );
|
else {
|
||||||
assertTrue( subEntityBindings.contains( subclassEntityBinding ) );
|
assertSame( otherSubclassEntityBinding, directSubEntityBinding1 );
|
||||||
assertTrue( subEntityBindings.contains( otherSubclassEntityBinding ) );
|
assertSame( subclassEntityBinding, directSubEntityBinding2 );
|
||||||
assertTrue( subEntityBindings.contains( subclassOfSubclassEntityBinding ) );
|
}
|
||||||
|
Set<AttributeBinding> directAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding attributeBinding : rootEntityBinding.attributeBindings() ) {
|
||||||
|
assertTrue( directAttributeBindings.add( attributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals( 1, directAttributeBindings.size() );
|
||||||
|
assertTrue( directAttributeBindings.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
assertEquals( 1, rootEntityBinding.getAttributeBindingClosureSpan() );
|
assertEquals( 1, rootEntityBinding.getAttributeBindingClosureSpan() );
|
||||||
Set<String> attributeNames = new HashSet<String>();
|
Set<AttributeBinding> attributeBindingClosure = new HashSet<AttributeBinding>();
|
||||||
for ( AttributeBinding attributeBinding : rootEntityBinding.getAttributeBindingClosure() ) {
|
for ( AttributeBinding attributeBinding : rootEntityBinding.getAttributeBindingClosure() ) {
|
||||||
attributeNames.add( attributeBinding.getAttribute().getName() );
|
assertTrue( attributeBindingClosure.add( attributeBinding ) );
|
||||||
}
|
}
|
||||||
assertEquals( 1, attributeNames.size() );
|
assertEquals( 1, attributeBindingClosure.size() );
|
||||||
assertTrue( attributeNames.contains( "id" ) );
|
assertTrue( attributeBindingClosure.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
Set<AttributeBinding> subAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding subAttributeBinding : rootEntityBinding.getSubEntityAttributeBindingClosure() ) {
|
||||||
|
assertTrue( subAttributeBindings.add( subAttributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals( 4, subAttributeBindings.size() );
|
||||||
|
assertTrue( subAttributeBindings.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( subclassEntityBinding.locateAttributeBinding( "name" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( subclassOfSubclassEntityBinding.locateAttributeBinding( "otherOtherName" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( otherSubclassEntityBinding.locateAttributeBinding( "otherName" ) ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Resources(annotatedClasses = {
|
||||||
|
SubclassOfSingleTableInheritance.class,
|
||||||
|
SingleEntity.class,
|
||||||
|
RootOfSingleTableInheritance.class,
|
||||||
|
OtherSubclassOfSingleTableInheritance.class,
|
||||||
|
SubclassOfSubclassOfSingleTableInheritance.class
|
||||||
|
})
|
||||||
|
public void testPreOrderRootSubEntityClosure() {
|
||||||
|
EntityBinding rootEntityBinding = getEntityBinding( RootOfSingleTableInheritance.class );
|
||||||
|
EntityBinding subclassEntityBinding = getEntityBinding( SubclassOfSingleTableInheritance.class );
|
||||||
|
EntityBinding otherSubclassEntityBinding = getEntityBinding( OtherSubclassOfSingleTableInheritance.class );
|
||||||
|
EntityBinding subclassOfSubclassEntityBinding = getEntityBinding( SubclassOfSubclassOfSingleTableInheritance.class );
|
||||||
|
// need to figure out the order of direct subclasses, since it's indeterminate
|
||||||
|
Iterator<EntityBinding> directEntityBindingIterator = rootEntityBinding.getDirectSubEntityBindings().iterator();
|
||||||
|
boolean isSubclassEntityBindingFirst = subclassEntityBinding == directEntityBindingIterator.next();
|
||||||
|
assertEquals( 3, rootEntityBinding.getSubEntityBindingClosureSpan() );
|
||||||
|
Iterator<EntityBinding> subEntityBindingIterator = rootEntityBinding.getPreOrderSubEntityBindingClosure().iterator();
|
||||||
|
assertTrue( subEntityBindingIterator.hasNext() );
|
||||||
|
if ( isSubclassEntityBindingFirst ) {
|
||||||
|
assertSame( subclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertTrue( subEntityBindingIterator.hasNext() );
|
||||||
|
assertSame( subclassOfSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertTrue( subEntityBindingIterator.hasNext() );
|
||||||
|
assertSame( otherSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertSame( otherSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertTrue( subEntityBindingIterator.hasNext() );
|
||||||
|
assertSame( subclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertTrue( subEntityBindingIterator.hasNext() );
|
||||||
|
assertSame( subclassOfSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
}
|
||||||
|
assertFalse( subEntityBindingIterator.hasNext() );
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@Resources(annotatedClasses = {
|
||||||
|
SubclassOfSingleTableInheritance.class,
|
||||||
|
SingleEntity.class,
|
||||||
|
RootOfSingleTableInheritance.class,
|
||||||
|
OtherSubclassOfSingleTableInheritance.class,
|
||||||
|
SubclassOfSubclassOfSingleTableInheritance.class
|
||||||
|
})
|
||||||
|
public void testPostOrderRootSubEntityClosure() {
|
||||||
|
EntityBinding rootEntityBinding = getEntityBinding( RootOfSingleTableInheritance.class );
|
||||||
|
EntityBinding subclassEntityBinding = getEntityBinding( SubclassOfSingleTableInheritance.class );
|
||||||
|
EntityBinding otherSubclassEntityBinding = getEntityBinding( OtherSubclassOfSingleTableInheritance.class );
|
||||||
|
EntityBinding subclassOfSubclassEntityBinding = getEntityBinding( SubclassOfSubclassOfSingleTableInheritance.class );
|
||||||
|
// need to figure out the order of direct subclasses, since it's indeterminate
|
||||||
|
Iterator<EntityBinding> directEntityBindingIterator = rootEntityBinding.getDirectSubEntityBindings().iterator();
|
||||||
|
boolean isSubclassEntityBindingFirst = subclassEntityBinding == directEntityBindingIterator.next();
|
||||||
|
assertEquals( 3, rootEntityBinding.getSubEntityBindingClosureSpan() );
|
||||||
|
Iterator<EntityBinding> subEntityBindingIterator = rootEntityBinding.getPostOrderSubEntityBindingClosure().iterator();
|
||||||
|
assertTrue( subEntityBindingIterator.hasNext() );
|
||||||
|
if ( isSubclassEntityBindingFirst ) {
|
||||||
|
assertSame( subclassOfSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertSame( subclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertSame( otherSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
assertSame( subclassOfSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertSame( otherSubclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
assertSame( subclassEntityBinding, subEntityBindingIterator.next() );
|
||||||
|
}
|
||||||
|
assertFalse( subEntityBindingIterator.hasNext() );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -189,16 +296,30 @@ public class InheritanceBindingTest extends BaseAnnotationBindingTestCase {
|
||||||
assertSame( rootEntityBinding, getRootEntityBinding( OtherSubclassOfSingleTableInheritance.class) );
|
assertSame( rootEntityBinding, getRootEntityBinding( OtherSubclassOfSingleTableInheritance.class) );
|
||||||
assertTrue( otherSubclassEntityBinding.isPolymorphic() );
|
assertTrue( otherSubclassEntityBinding.isPolymorphic() );
|
||||||
assertFalse( otherSubclassEntityBinding.hasSubEntityBindings() );
|
assertFalse( otherSubclassEntityBinding.hasSubEntityBindings() );
|
||||||
assertEquals( 0, otherSubclassEntityBinding.getSubEntityBindingSpan() );
|
assertEquals( 0, otherSubclassEntityBinding.getSubEntityBindingClosureSpan() );
|
||||||
assertFalse( otherSubclassEntityBinding.getSubEntityBindingClosure().iterator().hasNext() );
|
assertFalse( otherSubclassEntityBinding.getPostOrderSubEntityBindingClosure().iterator().hasNext() );
|
||||||
assertEquals( 2, otherSubclassEntityBinding.getAttributeBindingClosureSpan() );
|
assertFalse( otherSubclassEntityBinding.getPreOrderSubEntityBindingClosure().iterator().hasNext() );
|
||||||
Set<String> attributeNames = new HashSet<String>();
|
Set<AttributeBinding> directAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
for ( AttributeBinding attributeBinding : otherSubclassEntityBinding.getAttributeBindingClosure() ) {
|
for ( AttributeBinding attributeBinding : otherSubclassEntityBinding.attributeBindings() ) {
|
||||||
attributeNames.add( attributeBinding.getAttribute().getName() );
|
assertTrue( directAttributeBindings.add( attributeBinding ) );
|
||||||
}
|
}
|
||||||
assertEquals( 2, attributeNames.size() );
|
assertEquals( 1, directAttributeBindings.size() );
|
||||||
assertTrue( attributeNames.contains( "id" ) );
|
assertTrue( directAttributeBindings.contains( otherSubclassEntityBinding.locateAttributeBinding( "otherName" ) ) );
|
||||||
assertTrue( attributeNames.contains( "otherName" ) );
|
assertEquals( 2, otherSubclassEntityBinding.getAttributeBindingClosureSpan() );
|
||||||
|
Set<AttributeBinding> attributeBindingClosure = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding attributeBinding : otherSubclassEntityBinding.getAttributeBindingClosure() ) {
|
||||||
|
assertTrue( attributeBindingClosure.add( attributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals(2, attributeBindingClosure.size() );
|
||||||
|
assertTrue( attributeBindingClosure.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
assertTrue( attributeBindingClosure.contains( otherSubclassEntityBinding.locateAttributeBinding( "otherName" ) ) );
|
||||||
|
Set<AttributeBinding> subAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding subAttributeBinding : otherSubclassEntityBinding.getSubEntityAttributeBindingClosure() ) {
|
||||||
|
assertTrue( subAttributeBindings.add( subAttributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals( 2, subAttributeBindings.size() );
|
||||||
|
assertTrue( subAttributeBindings.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( otherSubclassEntityBinding.locateAttributeBinding( "otherName" ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -221,19 +342,37 @@ public class InheritanceBindingTest extends BaseAnnotationBindingTestCase {
|
||||||
assertSame( rootEntityBinding, getRootEntityBinding( SubclassOfSingleTableInheritance.class ) );
|
assertSame( rootEntityBinding, getRootEntityBinding( SubclassOfSingleTableInheritance.class ) );
|
||||||
assertTrue( subclassEntityBinding.isPolymorphic() );
|
assertTrue( subclassEntityBinding.isPolymorphic() );
|
||||||
assertTrue( subclassEntityBinding.hasSubEntityBindings() );
|
assertTrue( subclassEntityBinding.hasSubEntityBindings() );
|
||||||
assertEquals( 1, subclassEntityBinding.getSubEntityBindingSpan() );
|
assertEquals( 1, subclassEntityBinding.getSubEntityBindingClosureSpan() );
|
||||||
Iterator<EntityBinding> itSubEntityBindings = subclassEntityBinding.getSubEntityBindingClosure().iterator();
|
Iterator<EntityBinding> itSubEntityBindings = subclassEntityBinding.getPostOrderSubEntityBindingClosure().iterator();
|
||||||
assertTrue( itSubEntityBindings.hasNext() );
|
assertTrue( itSubEntityBindings.hasNext() );
|
||||||
assertSame( subclassOfSubclassEntityBinding, itSubEntityBindings.next() );
|
assertSame( subclassOfSubclassEntityBinding, itSubEntityBindings.next() );
|
||||||
assertFalse( itSubEntityBindings.hasNext() );
|
assertFalse( itSubEntityBindings.hasNext() );
|
||||||
assertEquals( 2, subclassEntityBinding.getAttributeBindingClosureSpan() );
|
itSubEntityBindings = subclassEntityBinding.getPreOrderSubEntityBindingClosure().iterator();
|
||||||
Set<String> attributeNames = new HashSet<String>();
|
assertTrue( itSubEntityBindings.hasNext() );
|
||||||
for ( AttributeBinding attributeBinding : subclassEntityBinding.getAttributeBindingClosure() ) {
|
assertSame( subclassOfSubclassEntityBinding, itSubEntityBindings.next() );
|
||||||
attributeNames.add( attributeBinding.getAttribute().getName() );
|
assertFalse( itSubEntityBindings.hasNext() );
|
||||||
|
Set<AttributeBinding> directAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding attributeBinding : subclassEntityBinding.attributeBindings() ) {
|
||||||
|
assertTrue( directAttributeBindings.add( attributeBinding ) );
|
||||||
}
|
}
|
||||||
assertEquals( 2, attributeNames.size() );
|
assertEquals( 1, directAttributeBindings.size() );
|
||||||
assertTrue( attributeNames.contains( "id" ) );
|
assertTrue( directAttributeBindings.contains( subclassEntityBinding.locateAttributeBinding( "name" ) ) );
|
||||||
assertTrue( attributeNames.contains( "name" ) );
|
assertEquals( 2, subclassEntityBinding.getAttributeBindingClosureSpan() );
|
||||||
|
Set<AttributeBinding> attributeBindingClosure = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding attributeBinding : subclassEntityBinding.getAttributeBindingClosure() ) {
|
||||||
|
assertTrue( attributeBindingClosure.add( attributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals( 2, attributeBindingClosure.size() );
|
||||||
|
assertTrue( attributeBindingClosure.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
assertTrue( attributeBindingClosure.contains( subclassEntityBinding.locateAttributeBinding( "name" ) ) );
|
||||||
|
Set<AttributeBinding> subAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding subAttributeBinding : subclassEntityBinding.getSubEntityAttributeBindingClosure() ) {
|
||||||
|
assertTrue( subAttributeBindings.add( subAttributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals( 3, subAttributeBindings.size() );
|
||||||
|
assertTrue( subAttributeBindings.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( subclassEntityBinding.locateAttributeBinding( "name" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( subclassOfSubclassEntityBinding.locateAttributeBinding( "otherOtherName" ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
@ -256,17 +395,32 @@ public class InheritanceBindingTest extends BaseAnnotationBindingTestCase {
|
||||||
assertSame( rootEntityBinding, getRootEntityBinding( SubclassOfSubclassOfSingleTableInheritance.class ) );
|
assertSame( rootEntityBinding, getRootEntityBinding( SubclassOfSubclassOfSingleTableInheritance.class ) );
|
||||||
assertTrue( subclassOfSubclassEntityBinding.isPolymorphic() );
|
assertTrue( subclassOfSubclassEntityBinding.isPolymorphic() );
|
||||||
assertFalse( subclassOfSubclassEntityBinding.hasSubEntityBindings() );
|
assertFalse( subclassOfSubclassEntityBinding.hasSubEntityBindings() );
|
||||||
assertEquals( 0, subclassOfSubclassEntityBinding.getSubEntityBindingSpan() );
|
assertEquals( 0, subclassOfSubclassEntityBinding.getSubEntityBindingClosureSpan() );
|
||||||
assertFalse( subclassOfSubclassEntityBinding.getSubEntityBindingClosure().iterator().hasNext() );
|
assertFalse( subclassOfSubclassEntityBinding.getPostOrderSubEntityBindingClosure().iterator().hasNext() );
|
||||||
assertEquals( 3, subclassOfSubclassEntityBinding.getAttributeBindingClosureSpan() );
|
assertFalse( subclassOfSubclassEntityBinding.getPreOrderSubEntityBindingClosure().iterator().hasNext() );
|
||||||
Set<String> attributeNames = new HashSet<String>();
|
Set<AttributeBinding> directAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
for ( AttributeBinding attributeBinding : subclassOfSubclassEntityBinding.getAttributeBindingClosure() ) {
|
for ( AttributeBinding attributeBinding : subclassOfSubclassEntityBinding.attributeBindings() ) {
|
||||||
attributeNames.add( attributeBinding.getAttribute().getName() );
|
assertTrue( directAttributeBindings.add( attributeBinding ) );
|
||||||
}
|
}
|
||||||
assertEquals( 3, attributeNames.size() );
|
assertEquals( 1, directAttributeBindings.size() );
|
||||||
assertTrue( attributeNames.contains( "id" ) );
|
assertTrue( directAttributeBindings.contains( subclassOfSubclassEntityBinding.locateAttributeBinding( "otherOtherName" ) ) );
|
||||||
assertTrue( attributeNames.contains( "name" ) );
|
assertEquals( 3, subclassOfSubclassEntityBinding.getAttributeBindingClosureSpan() );
|
||||||
assertTrue( attributeNames.contains( "otherOtherName" ) );
|
Set<AttributeBinding> attributeBindingClosure = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding attributeBinding : subclassOfSubclassEntityBinding.getAttributeBindingClosure() ) {
|
||||||
|
assertTrue( attributeBindingClosure.add( attributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals( 3, attributeBindingClosure.size() );
|
||||||
|
assertTrue( attributeBindingClosure.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
assertTrue( attributeBindingClosure.contains( subclassEntityBinding.locateAttributeBinding( "name" ) ) );
|
||||||
|
assertTrue( attributeBindingClosure.contains( subclassOfSubclassEntityBinding.locateAttributeBinding( "otherOtherName" ) ) );
|
||||||
|
Set<AttributeBinding> subAttributeBindings = new HashSet<AttributeBinding>();
|
||||||
|
for ( AttributeBinding subAttributeBinding : subclassOfSubclassEntityBinding.getSubEntityAttributeBindingClosure() ) {
|
||||||
|
assertTrue( subAttributeBindings.add( subAttributeBinding ) );
|
||||||
|
}
|
||||||
|
assertEquals( 3, subAttributeBindings.size() );
|
||||||
|
assertTrue( subAttributeBindings.contains( rootEntityBinding.locateAttributeBinding( "id" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( subclassEntityBinding.locateAttributeBinding( "name" ) ) );
|
||||||
|
assertTrue( subAttributeBindings.contains( subclassOfSubclassEntityBinding.locateAttributeBinding( "otherOtherName" ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
//$Id: Employee.java 4373 2004-08-18 09:18:34Z oneovthafew $
|
||||||
|
package org.hibernate.test.discriminator;
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gail Badner
|
||||||
|
*/
|
||||||
|
public class PartTimeEmployee extends Employee {
|
||||||
|
private String title;
|
||||||
|
private BigDecimal salary;
|
||||||
|
private Employee manager;
|
||||||
|
private int percent;
|
||||||
|
|
||||||
|
public int getPercent() {
|
||||||
|
return percent;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setPercent(int percent) {
|
||||||
|
this.percent = percent;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,60 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<hibernate-mapping package="org.hibernate.test.discriminator" default-access="field"
|
||||||
|
xmlns="http://www.hibernate.org/xsd/hibernate-mapping"
|
||||||
|
xsi:schemaLocation="http://www.hibernate.org/xsd/hibernate-mapping hibernate-mapping-4.0.xsd"
|
||||||
|
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance">
|
||||||
|
|
||||||
|
<!--
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://www.hibernate.org/dtd/hibernate-mapping-3.0.dtd">
|
||||||
|
<hibernate-mapping
|
||||||
|
package="org.hibernate.test.discriminator"
|
||||||
|
default-access="field">
|
||||||
|
-->
|
||||||
|
<!--
|
||||||
|
|
||||||
|
This mapping demonstrates a simple table-per-hierarchy mapping strategy;
|
||||||
|
each subclass has simple properties
|
||||||
|
|
||||||
|
-->
|
||||||
|
|
||||||
|
<class name="Person"
|
||||||
|
discriminator-value="P">
|
||||||
|
|
||||||
|
<id name="id"
|
||||||
|
column="person_id"
|
||||||
|
unsaved-value="0">
|
||||||
|
<generator class="assigned"/>
|
||||||
|
</id>
|
||||||
|
|
||||||
|
<discriminator column="TYPE" type="character"/>
|
||||||
|
|
||||||
|
<property name="name"
|
||||||
|
not-null="true"
|
||||||
|
length="80"/>
|
||||||
|
|
||||||
|
<property name="sex"
|
||||||
|
not-null="true"
|
||||||
|
update="false"/>
|
||||||
|
|
||||||
|
<subclass name="Employee"
|
||||||
|
discriminator-value="E">
|
||||||
|
<property name="title" length="20"/>
|
||||||
|
<property name="salary" />
|
||||||
|
<!-- commented out until HHH-6551 is fixed
|
||||||
|
<subclass name="PartTimeEmployee" discriminator-value="M">
|
||||||
|
<property name="percent"/>
|
||||||
|
</subclass>
|
||||||
|
-->
|
||||||
|
</subclass>
|
||||||
|
|
||||||
|
<subclass name="Customer"
|
||||||
|
discriminator-value="C">
|
||||||
|
<property name="comments"/>
|
||||||
|
</subclass>
|
||||||
|
|
||||||
|
</class>
|
||||||
|
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,271 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2006-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.test.discriminator;
|
||||||
|
|
||||||
|
import java.math.BigDecimal;
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Transaction;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.criterion.Property;
|
||||||
|
import org.hibernate.criterion.Restrictions;
|
||||||
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
|
import org.hibernate.testing.junit4.BaseCoreFunctionalTestCase;
|
||||||
|
|
||||||
|
import static org.junit.Assert.assertEquals;
|
||||||
|
import static org.junit.Assert.assertFalse;
|
||||||
|
import static org.junit.Assert.assertNotNull;
|
||||||
|
import static org.junit.Assert.assertNull;
|
||||||
|
import static org.junit.Assert.assertSame;
|
||||||
|
import static org.junit.Assert.assertTrue;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Gavin King
|
||||||
|
*/
|
||||||
|
public class SimpleInheritanceTest extends BaseCoreFunctionalTestCase {
|
||||||
|
public void configure(Configuration cfg) {
|
||||||
|
super.configure( cfg );
|
||||||
|
cfg.setProperty( USE_NEW_METADATA_MAPPINGS, "true");
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String[] getMappings() {
|
||||||
|
return new String[] { "discriminator/SimpleInheritance.hbm.xml" };
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testDiscriminatorSubclass() {
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
|
||||||
|
Employee mark = new Employee();
|
||||||
|
mark.setId( 1 );
|
||||||
|
mark.setName( "Mark" );
|
||||||
|
mark.setTitle( "internal sales" );
|
||||||
|
mark.setSex( 'M' );
|
||||||
|
|
||||||
|
Customer joe = new Customer();
|
||||||
|
joe.setId( 2 );
|
||||||
|
joe.setName( "Joe" );
|
||||||
|
joe.setComments( "Very demanding" );
|
||||||
|
joe.setSex( 'M' );
|
||||||
|
|
||||||
|
Person yomomma = new Person();
|
||||||
|
yomomma.setId( 3 );
|
||||||
|
yomomma.setName("mum");
|
||||||
|
yomomma.setSex('F');
|
||||||
|
|
||||||
|
s.save(yomomma);
|
||||||
|
s.save(mark);
|
||||||
|
s.save(joe);
|
||||||
|
|
||||||
|
assertEquals( s.createQuery("from java.io.Serializable").list().size(), 0 );
|
||||||
|
|
||||||
|
assertEquals( s.createQuery("from org.hibernate.test.discriminator.Person").list().size(), 3 );
|
||||||
|
assertEquals( s.createQuery("from org.hibernate.test.discriminator.Person p where p.class = org.hibernate.test.discriminator.Person").list().size(), 1 );
|
||||||
|
assertEquals( s.createQuery("from org.hibernate.test.discriminator.Person p where p.class = org.hibernate.test.discriminator.Customer").list().size(), 1 );
|
||||||
|
s.clear();
|
||||||
|
|
||||||
|
List customers = s.createQuery("from org.hibernate.test.discriminator.Customer").list();
|
||||||
|
for ( Object customer : customers ) {
|
||||||
|
Customer c = (Customer) customer;
|
||||||
|
assertEquals( "Very demanding", c.getComments() );
|
||||||
|
}
|
||||||
|
assertEquals( customers.size(), 1 );
|
||||||
|
s.clear();
|
||||||
|
|
||||||
|
mark = (Employee) s.get( Employee.class, mark.getId() );
|
||||||
|
joe = (Customer) s.get( Customer.class, joe.getId() );
|
||||||
|
|
||||||
|
s.delete(mark);
|
||||||
|
s.delete(joe);
|
||||||
|
s.delete(yomomma);
|
||||||
|
assertTrue( s.createQuery("from org.hibernate.test.discriminator.Person").list().isEmpty() );
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testAccessAsIncorrectSubclass() {
|
||||||
|
Session s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
Employee e = new Employee();
|
||||||
|
e.setId( 4 );
|
||||||
|
e.setName( "Steve" );
|
||||||
|
e.setSex( 'M' );
|
||||||
|
e.setTitle( "grand poobah" );
|
||||||
|
s.save( e );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
Customer c = ( Customer ) s.get( Customer.class, e.getId() );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
assertNull( c );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
e = ( Employee ) s.get( Employee.class, e.getId() );
|
||||||
|
c = ( Customer ) s.get( Customer.class, e.getId() );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
assertNotNull( e );
|
||||||
|
assertNull( c );
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
s.delete( e );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testQuerySubclassAttribute() {
|
||||||
|
Session s = openSession();
|
||||||
|
Transaction t = s.beginTransaction();
|
||||||
|
Person p = new Person();
|
||||||
|
p.setId( 5 );
|
||||||
|
p.setName("Emmanuel");
|
||||||
|
p.setSex('M');
|
||||||
|
s.save( p );
|
||||||
|
Employee q = new Employee();
|
||||||
|
q.setId( 6 );
|
||||||
|
q.setName("Steve");
|
||||||
|
q.setSex('M');
|
||||||
|
q.setTitle("Mr");
|
||||||
|
q.setSalary( new BigDecimal(1000) );
|
||||||
|
s.save( q );
|
||||||
|
|
||||||
|
List result = s.createQuery("from org.hibernate.test.discriminator.Person where salary > 100").list();
|
||||||
|
assertEquals( result.size(), 1 );
|
||||||
|
assertSame( result.get(0), q );
|
||||||
|
|
||||||
|
result = s.createQuery("from org.hibernate.test.discriminator.Person where salary > 100 or name like 'E%'").list();
|
||||||
|
assertEquals( result.size(), 2 );
|
||||||
|
|
||||||
|
result = s.createCriteria(Person.class)
|
||||||
|
.add( Property.forName("salary").gt( new BigDecimal(100) ) )
|
||||||
|
.list();
|
||||||
|
assertEquals( result.size(), 1 );
|
||||||
|
assertSame( result.get(0), q );
|
||||||
|
|
||||||
|
//TODO: make this work:
|
||||||
|
/*result = s.createQuery("select salary from Person where salary > 100").list();
|
||||||
|
assertEquals( result.size(), 1 );
|
||||||
|
assertEquals( result.get(0), new BigDecimal(1000) );*/
|
||||||
|
|
||||||
|
s.delete(p);
|
||||||
|
s.delete(q);
|
||||||
|
t.commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadSuperclassProxyPolymorphicAccess() {
|
||||||
|
Session s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
Employee e = new Employee();
|
||||||
|
e.setId( 7 );
|
||||||
|
e.setName( "Steve" );
|
||||||
|
e.setSex( 'M' );
|
||||||
|
e.setTitle( "grand poobah" );
|
||||||
|
s.save( e );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
// load the superclass proxy.
|
||||||
|
Person pLoad = ( Person ) s.load( Person.class, new Long( e.getId() ) );
|
||||||
|
assertTrue( pLoad instanceof HibernateProxy);
|
||||||
|
Person pGet = ( Person ) s.get( Person.class, e.getId());
|
||||||
|
Person pQuery = ( Person ) s.createQuery( "from org.hibernate.test.discriminator.Person where id = :id" )
|
||||||
|
.setLong( "id", e.getId() )
|
||||||
|
.uniqueResult();
|
||||||
|
Person pCriteria = ( Person ) s.createCriteria( Person.class )
|
||||||
|
.add( Restrictions.idEq( e.getId() ) )
|
||||||
|
.uniqueResult();
|
||||||
|
// assert that executing the queries polymorphically returns the same proxy
|
||||||
|
assertSame( pLoad, pGet );
|
||||||
|
assertSame( pLoad, pQuery );
|
||||||
|
assertSame( pLoad, pCriteria );
|
||||||
|
|
||||||
|
// assert that the proxy is not an instance of Employee
|
||||||
|
assertFalse( pLoad instanceof Employee );
|
||||||
|
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
s.delete( e );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
public void testLoadSuperclassProxyEvictPolymorphicAccess() {
|
||||||
|
Session s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
Employee e = new Employee();
|
||||||
|
e.setId( 8 );
|
||||||
|
e.setName( "Steve" );
|
||||||
|
e.setSex( 'M' );
|
||||||
|
e.setTitle( "grand poobah" );
|
||||||
|
s.save( e );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
// load the superclass proxy.
|
||||||
|
Person pLoad = ( Person ) s.load( Person.class, new Long( e.getId() ) );
|
||||||
|
assertTrue( pLoad instanceof HibernateProxy);
|
||||||
|
// evict the proxy
|
||||||
|
s.evict( pLoad );
|
||||||
|
Employee pGet = ( Employee ) s.get( Person.class, e.getId() );
|
||||||
|
Employee pQuery = ( Employee ) s.createQuery( "from org.hibernate.test.discriminator.Person where id = :id" )
|
||||||
|
.setLong( "id", e.getId() )
|
||||||
|
.uniqueResult();
|
||||||
|
Employee pCriteria = ( Employee ) s.createCriteria( Person.class )
|
||||||
|
.add( Restrictions.idEq( e.getId() ) )
|
||||||
|
.uniqueResult();
|
||||||
|
// assert that executing the queries polymorphically returns the same Employee instance
|
||||||
|
assertSame( pGet, pQuery );
|
||||||
|
assertSame( pGet, pCriteria );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
|
||||||
|
s = openSession();
|
||||||
|
s.beginTransaction();
|
||||||
|
s.delete( e );
|
||||||
|
s.getTransaction().commit();
|
||||||
|
s.close();
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue