HHH-3515 : EntityNameResolver
git-svn-id: https://svn.jboss.org/repos/hibernate/core/trunk@15258 1b8cb986-b30d-0410-93ca-fae66ebed9b2
This commit is contained in:
parent
86eeb9be34
commit
c3d4758f1e
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||||
|
*
|
||||||
|
* 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;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Contract for resolving an entity-name from a given entity instance.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public interface EntityNameResolver {
|
||||||
|
/**
|
||||||
|
* Given an entity instance, determine its entity-name.
|
||||||
|
*
|
||||||
|
* @param entity The entity instance.
|
||||||
|
*
|
||||||
|
* @return The corresponding entity-name, or null if this impl does not know how to perform resolution
|
||||||
|
* for the given entity instance.
|
||||||
|
*/
|
||||||
|
public String resolveEntityName(Object entity);
|
||||||
|
}
|
|
@ -39,6 +39,7 @@ import java.util.Iterator;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Properties;
|
import java.util.Properties;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
|
import java.util.LinkedHashSet;
|
||||||
import javax.naming.NamingException;
|
import javax.naming.NamingException;
|
||||||
import javax.naming.Reference;
|
import javax.naming.Reference;
|
||||||
import javax.naming.StringRefAddr;
|
import javax.naming.StringRefAddr;
|
||||||
|
@ -58,6 +59,8 @@ import org.hibernate.QueryException;
|
||||||
import org.hibernate.SessionFactory;
|
import org.hibernate.SessionFactory;
|
||||||
import org.hibernate.StatelessSession;
|
import org.hibernate.StatelessSession;
|
||||||
import org.hibernate.SessionFactoryObserver;
|
import org.hibernate.SessionFactoryObserver;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
|
import org.hibernate.tuple.entity.EntityTuplizer;
|
||||||
import org.hibernate.cache.CacheKey;
|
import org.hibernate.cache.CacheKey;
|
||||||
import org.hibernate.cache.CollectionRegion;
|
import org.hibernate.cache.CollectionRegion;
|
||||||
import org.hibernate.cache.EntityRegion;
|
import org.hibernate.cache.EntityRegion;
|
||||||
|
@ -117,6 +120,7 @@ import org.hibernate.type.AssociationType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.util.CollectionHelper;
|
import org.hibernate.util.CollectionHelper;
|
||||||
import org.hibernate.util.ReflectHelper;
|
import org.hibernate.util.ReflectHelper;
|
||||||
|
import org.hibernate.util.EmptyIterator;
|
||||||
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -177,6 +181,7 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
|
||||||
private final transient EntityNotFoundDelegate entityNotFoundDelegate;
|
private final transient EntityNotFoundDelegate entityNotFoundDelegate;
|
||||||
private final transient SQLFunctionRegistry sqlFunctionRegistry;
|
private final transient SQLFunctionRegistry sqlFunctionRegistry;
|
||||||
private final transient SessionFactoryObserver observer;
|
private final transient SessionFactoryObserver observer;
|
||||||
|
private final transient HashMap entityNameResolvers = new HashMap();
|
||||||
|
|
||||||
private final QueryPlanCache queryPlanCache = new QueryPlanCache( this );
|
private final QueryPlanCache queryPlanCache = new QueryPlanCache( this );
|
||||||
|
|
||||||
|
@ -325,11 +330,15 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
|
||||||
// after *all* persisters and named queries are registered
|
// after *all* persisters and named queries are registered
|
||||||
Iterator iter = entityPersisters.values().iterator();
|
Iterator iter = entityPersisters.values().iterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
( (EntityPersister) iter.next() ).postInstantiate();
|
final EntityPersister persister = ( ( EntityPersister ) iter.next() );
|
||||||
|
persister.postInstantiate();
|
||||||
|
registerEntityNameResolvers( persister );
|
||||||
|
|
||||||
}
|
}
|
||||||
iter = collectionPersisters.values().iterator();
|
iter = collectionPersisters.values().iterator();
|
||||||
while ( iter.hasNext() ) {
|
while ( iter.hasNext() ) {
|
||||||
( (CollectionPersister) iter.next() ).postInstantiate();
|
final CollectionPersister persister = ( ( CollectionPersister ) iter.next() );
|
||||||
|
persister.postInstantiate();
|
||||||
}
|
}
|
||||||
|
|
||||||
//JNDI + Serialization:
|
//JNDI + Serialization:
|
||||||
|
@ -458,6 +467,41 @@ public final class SessionFactoryImpl implements SessionFactory, SessionFactoryI
|
||||||
this.observer.sessionFactoryCreated( this );
|
this.observer.sessionFactoryCreated( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void registerEntityNameResolvers(EntityPersister persister) {
|
||||||
|
Iterator itr = persister.getEntityMetamodel().getTuplizerMapping().iterateTuplizers();
|
||||||
|
while ( itr.hasNext() ) {
|
||||||
|
final EntityTuplizer tuplizer = ( EntityTuplizer ) itr.next();
|
||||||
|
registerEntityNameResolvers( tuplizer );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void registerEntityNameResolvers(EntityTuplizer tuplizer) {
|
||||||
|
EntityNameResolver[] resolvers = tuplizer.getEntityNameResolvers();
|
||||||
|
if ( resolvers == null ) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
for ( int i = 0; i < resolvers.length; i++ ) {
|
||||||
|
registerEntityNameResolver( resolvers[i], tuplizer.getEntityMode() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void registerEntityNameResolver(EntityNameResolver resolver, EntityMode entityMode) {
|
||||||
|
LinkedHashSet resolversForMode = ( LinkedHashSet ) entityNameResolvers.get( entityMode );
|
||||||
|
if ( resolversForMode == null ) {
|
||||||
|
resolversForMode = new LinkedHashSet();
|
||||||
|
entityNameResolvers.put( entityMode, resolversForMode );
|
||||||
|
}
|
||||||
|
resolversForMode.add( resolver );
|
||||||
|
}
|
||||||
|
|
||||||
|
public Iterator iterateEntityNameResolvers(EntityMode entityMode) {
|
||||||
|
Set actualEntityNameResolvers = ( Set ) entityNameResolvers.get( entityMode );
|
||||||
|
return actualEntityNameResolvers == null
|
||||||
|
? EmptyIterator.INSTANCE
|
||||||
|
: actualEntityNameResolvers.iterator();
|
||||||
|
}
|
||||||
|
|
||||||
public QueryPlanCache getQueryPlanCache() {
|
public QueryPlanCache getQueryPlanCache() {
|
||||||
return queryPlanCache;
|
return queryPlanCache;
|
||||||
}
|
}
|
||||||
|
|
|
@ -67,6 +67,7 @@ import org.hibernate.Transaction;
|
||||||
import org.hibernate.TransientObjectException;
|
import org.hibernate.TransientObjectException;
|
||||||
import org.hibernate.UnresolvableObjectException;
|
import org.hibernate.UnresolvableObjectException;
|
||||||
import org.hibernate.UnknownProfileException;
|
import org.hibernate.UnknownProfileException;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
import org.hibernate.collection.PersistentCollection;
|
import org.hibernate.collection.PersistentCollection;
|
||||||
import org.hibernate.engine.ActionQueue;
|
import org.hibernate.engine.ActionQueue;
|
||||||
import org.hibernate.engine.CollectionEntry;
|
import org.hibernate.engine.CollectionEntry;
|
||||||
|
@ -127,6 +128,7 @@ import org.hibernate.proxy.LazyInitializer;
|
||||||
import org.hibernate.stat.SessionStatistics;
|
import org.hibernate.stat.SessionStatistics;
|
||||||
import org.hibernate.stat.SessionStatisticsImpl;
|
import org.hibernate.stat.SessionStatisticsImpl;
|
||||||
import org.hibernate.tuple.DynamicMapInstantiator;
|
import org.hibernate.tuple.DynamicMapInstantiator;
|
||||||
|
import org.hibernate.tuple.entity.PojoEntityTuplizer;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.util.ArrayHelper;
|
import org.hibernate.util.ArrayHelper;
|
||||||
import org.hibernate.util.CollectionHelper;
|
import org.hibernate.util.CollectionHelper;
|
||||||
|
@ -175,6 +177,30 @@ public final class SessionImpl extends AbstractSessionImpl
|
||||||
private transient Session rootSession;
|
private transient Session rootSession;
|
||||||
private transient Map childSessionsByEntityMode;
|
private transient Map childSessionsByEntityMode;
|
||||||
|
|
||||||
|
private EntityNameResolver entityNameResolver = new EntityNameResolver() {
|
||||||
|
public String resolveEntityName(Object entity) {
|
||||||
|
String entityName = interceptor.getEntityName( entity );
|
||||||
|
if ( entityName != null ) {
|
||||||
|
return entityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
Iterator itr = factory.iterateEntityNameResolvers( entityMode );
|
||||||
|
while ( itr.hasNext() ) {
|
||||||
|
final EntityNameResolver resolver = ( EntityNameResolver ) itr.next();
|
||||||
|
entityName = resolver.resolveEntityName( entity );
|
||||||
|
if ( entityName != null ) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ( entityName != null ) {
|
||||||
|
return entityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
// the old-time stand-by...
|
||||||
|
return entity.getClass().getName();
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor used in building "child sessions".
|
* Constructor used in building "child sessions".
|
||||||
*
|
*
|
||||||
|
@ -1724,23 +1750,7 @@ public final class SessionImpl extends AbstractSessionImpl
|
||||||
|
|
||||||
public String guessEntityName(Object object) throws HibernateException {
|
public String guessEntityName(Object object) throws HibernateException {
|
||||||
errorIfClosed();
|
errorIfClosed();
|
||||||
String entity = interceptor.getEntityName( object );
|
return entityNameResolver.resolveEntityName( object );
|
||||||
if ( entity == null ) {
|
|
||||||
if ( object instanceof Map ) {
|
|
||||||
entity = (String) ( (Map) object ).get( DynamicMapInstantiator.KEY );
|
|
||||||
if ( entity == null ) {
|
|
||||||
throw new HibernateException( "could not determine type of dynamic entity" );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if ( object instanceof Element ) {
|
|
||||||
// TODO : really need to keep a map of nodeName -> entityName, but that would mean nodeName being distinct
|
|
||||||
entity = ( (Element) object ).getName();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
entity = object.getClass().getName();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return entity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void cancelQuery() throws HibernateException {
|
public void cancelQuery() throws HibernateException {
|
||||||
|
|
|
@ -132,7 +132,6 @@ public abstract class AbstractEntityPersister
|
||||||
private final boolean isLazyPropertiesCacheable;
|
private final boolean isLazyPropertiesCacheable;
|
||||||
private final CacheEntryStructure cacheEntryStructure;
|
private final CacheEntryStructure cacheEntryStructure;
|
||||||
private final EntityMetamodel entityMetamodel;
|
private final EntityMetamodel entityMetamodel;
|
||||||
private final Map entityNameBySubclass = new HashMap();
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
private final String[] rootTableKeyColumnNames;
|
private final String[] rootTableKeyColumnNames;
|
||||||
|
@ -456,15 +455,6 @@ public abstract class AbstractEntityPersister
|
||||||
(CacheEntryStructure) new UnstructuredCacheEntry();
|
(CacheEntryStructure) new UnstructuredCacheEntry();
|
||||||
|
|
||||||
this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
|
this.entityMetamodel = new EntityMetamodel( persistentClass, factory );
|
||||||
|
|
||||||
if ( persistentClass.hasPojoRepresentation() ) {
|
|
||||||
//TODO: this is currently specific to pojos, but need to be available for all entity-modes
|
|
||||||
Iterator iter = persistentClass.getSubclassIterator();
|
|
||||||
while ( iter.hasNext() ) {
|
|
||||||
PersistentClass pc = ( PersistentClass ) iter.next();
|
|
||||||
entityNameBySubclass.put( pc.getMappedClass(), pc.getEntityName() );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
int batch = persistentClass.getBatchSize();
|
int batch = persistentClass.getBatchSize();
|
||||||
|
@ -3302,10 +3292,6 @@ public abstract class AbstractEntityPersister
|
||||||
return entityMetamodel.getEntityType();
|
return entityMetamodel.getEntityType();
|
||||||
}
|
}
|
||||||
|
|
||||||
private String getSubclassEntityName(Class clazz) {
|
|
||||||
return ( String ) entityNameBySubclass.get( clazz );
|
|
||||||
}
|
|
||||||
|
|
||||||
public boolean isPolymorphic() {
|
public boolean isPolymorphic() {
|
||||||
return entityMetamodel.isPolymorphic();
|
return entityMetamodel.isPolymorphic();
|
||||||
}
|
}
|
||||||
|
@ -3694,29 +3680,17 @@ public abstract class AbstractEntityPersister
|
||||||
getTuplizer( entityMode ).resetIdentifier( entity, currentId, currentVersion );
|
getTuplizer( entityMode ).resetIdentifier( entity, currentId, currentVersion );
|
||||||
}
|
}
|
||||||
|
|
||||||
public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode) {
|
public EntityPersister getSubclassEntityPersister(
|
||||||
|
Object instance,
|
||||||
|
SessionFactoryImplementor factory,
|
||||||
|
EntityMode entityMode) {
|
||||||
if ( !hasSubclasses() ) {
|
if ( !hasSubclasses() ) {
|
||||||
return this;
|
return this;
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// TODO : really need a way to do something like :
|
final String concreteEntityName = getTuplizer( entityMode )
|
||||||
// getTuplizer(entityMode).determineConcreteSubclassEntityName(instance)
|
.determineConcreteSubclassEntityName( instance, factory );
|
||||||
Class clazz = instance.getClass();
|
return factory.getEntityPersister( concreteEntityName );
|
||||||
if ( clazz == getMappedClass( entityMode ) ) {
|
|
||||||
return this;
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
String subclassEntityName = getSubclassEntityName( clazz );
|
|
||||||
if ( subclassEntityName == null ) {
|
|
||||||
throw new HibernateException(
|
|
||||||
"instance not of expected entity type: " + clazz.getName() +
|
|
||||||
" is not a: " + getEntityName()
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return factory.getEntityPersister( subclassEntityName );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -668,15 +668,35 @@ public interface EntityPersister extends OptimisticCacheSource {
|
||||||
public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode);
|
public boolean hasUninitializedLazyProperties(Object object, EntityMode entityMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Set the identifier and version of the given instance back
|
* Set the identifier and version of the given instance back to its "unsaved" value.
|
||||||
* to its "unsaved" value, returning the id
|
*
|
||||||
* @param currentId TODO
|
* @param entity The entity instance
|
||||||
* @param currentVersion TODO
|
* @param currentId The currently assigned identifier value.
|
||||||
|
* @param currentVersion The currently assigned version value.
|
||||||
|
* @param entityMode The entity mode represented by the entity instance.
|
||||||
*/
|
*/
|
||||||
public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode);
|
public void resetIdentifier(Object entity, Serializable currentId, Object currentVersion, EntityMode entityMode);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the persister for an instance of this class or a subclass
|
* A request has already identified the entity-name of this persister as the mapping for the given instance.
|
||||||
|
* However, we still need to account for possible subclassing and potentially re-route to the more appropriate
|
||||||
|
* persister.
|
||||||
|
* <p/>
|
||||||
|
* For example, a request names <tt>Animal</tt> as the entity-name which gets resolved to this persister. But the
|
||||||
|
* actual instance is really an instance of <tt>Cat</tt> which is a subclass of <tt>Animal</tt>. So, here the
|
||||||
|
* <tt>Animal</tt> persister is being asked to return the persister specific to <tt>Cat</tt>.
|
||||||
|
* <p/>
|
||||||
|
* It is also possible that the instance is actually an <tt>Animal</tt> instance in the above example in which
|
||||||
|
* case we would retrn <tt>this</tt> from this method.
|
||||||
|
*
|
||||||
|
* @param instance The entity instance
|
||||||
|
* @param factory Reference to the SessionFactory
|
||||||
|
* @param entityMode The entity mode represented by the entity instance.
|
||||||
|
*
|
||||||
|
* @return The appropriate persister
|
||||||
|
*
|
||||||
|
* @throws HibernateException Indicates that instance was deemed to not be a subclass of the entity mapped by
|
||||||
|
* this persister.
|
||||||
*/
|
*/
|
||||||
public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode);
|
public EntityPersister getSubclassEntityPersister(Object instance, SessionFactoryImplementor factory, EntityMode entityMode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -54,6 +54,15 @@ public abstract class EntityModeToTuplizerMapping implements Serializable {
|
||||||
tuplizers.put( entityMode, tuplizer );
|
tuplizers.put( entityMode, tuplizer );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Allow iteration over all defined {@link Tuplizer Tuplizers}.
|
||||||
|
*
|
||||||
|
* @return Iterator over defined tuplizers
|
||||||
|
*/
|
||||||
|
public Iterator iterateTuplizers() {
|
||||||
|
return tuplizers.values().iterator();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Given a supposed instance of an entity/component, guess its entity mode.
|
* Given a supposed instance of an entity/component, guess its entity mode.
|
||||||
*
|
*
|
||||||
|
|
|
@ -73,13 +73,6 @@ public abstract class AbstractEntityTuplizer implements EntityTuplizer {
|
||||||
private final AbstractComponentType identifierMapperType;
|
private final AbstractComponentType identifierMapperType;
|
||||||
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Return the entity-mode handled by this tuplizer instance.
|
|
||||||
*
|
|
||||||
* @return The entity-mode
|
|
||||||
*/
|
|
||||||
protected abstract EntityMode getEntityMode();
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Build an appropriate Getter for the given property.
|
* Build an appropriate Getter for the given property.
|
||||||
*
|
*
|
||||||
|
|
|
@ -35,6 +35,8 @@ import org.hibernate.property.Getter;
|
||||||
import org.hibernate.property.Setter;
|
import org.hibernate.property.Setter;
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
|
import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
import org.hibernate.tuple.Instantiator;
|
import org.hibernate.tuple.Instantiator;
|
||||||
import org.hibernate.tuple.Dom4jInstantiator;
|
import org.hibernate.tuple.Dom4jInstantiator;
|
||||||
import org.hibernate.type.AbstractComponentType;
|
import org.hibernate.type.AbstractComponentType;
|
||||||
|
@ -44,8 +46,9 @@ import org.slf4j.LoggerFactory;
|
||||||
|
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
import java.util.Set;
|
|
||||||
import java.util.Iterator;
|
import java.util.Iterator;
|
||||||
|
import java.util.Map;
|
||||||
|
import java.util.HashMap;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* An {@link EntityTuplizer} specific to the dom4j entity mode.
|
* An {@link EntityTuplizer} specific to the dom4j entity mode.
|
||||||
|
@ -57,17 +60,21 @@ public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
|
|
||||||
static final Logger log = LoggerFactory.getLogger( Dom4jEntityTuplizer.class );
|
static final Logger log = LoggerFactory.getLogger( Dom4jEntityTuplizer.class );
|
||||||
|
|
||||||
private Set subclassNodeNames = new HashSet();
|
private Map inheritenceNodeNameMap = new HashMap();
|
||||||
|
|
||||||
Dom4jEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
Dom4jEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
||||||
super(entityMetamodel, mappedEntity);
|
super( entityMetamodel, mappedEntity );
|
||||||
|
inheritenceNodeNameMap.put( mappedEntity.getNodeName(), mappedEntity.getEntityName() );
|
||||||
Iterator itr = mappedEntity.getSubclassClosureIterator();
|
Iterator itr = mappedEntity.getSubclassClosureIterator();
|
||||||
while( itr.hasNext() ) {
|
while( itr.hasNext() ) {
|
||||||
final PersistentClass mapping = ( PersistentClass ) itr.next();
|
final PersistentClass mapping = ( PersistentClass ) itr.next();
|
||||||
subclassNodeNames.add( mapping.getNodeName() );
|
inheritenceNodeNameMap.put( mapping.getNodeName(), mapping.getEntityName() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public EntityMode getEntityMode() {
|
public EntityMode getEntityMode() {
|
||||||
return EntityMode.DOM4J;
|
return EntityMode.DOM4J;
|
||||||
}
|
}
|
||||||
|
@ -85,18 +92,30 @@ public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
|
protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
|
||||||
return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
|
return buildPropertyAccessor(mappedProperty).getGetter( null, mappedProperty.getName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
|
protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
|
||||||
return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
|
return buildPropertyAccessor(mappedProperty).getSetter( null, mappedProperty.getName() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
||||||
return new Dom4jInstantiator( persistentClass );
|
return new Dom4jInstantiator( persistentClass );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Serializable getIdentifier(Object entityOrId) throws HibernateException {
|
public Serializable getIdentifier(Object entityOrId) throws HibernateException {
|
||||||
if (entityOrId instanceof Element) {
|
if (entityOrId instanceof Element) {
|
||||||
return super.getIdentifier(entityOrId);
|
return super.getIdentifier(entityOrId);
|
||||||
|
@ -107,6 +126,9 @@ public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
|
protected ProxyFactory buildProxyFactory(PersistentClass mappingInfo, Getter idGetter, Setter idSetter) {
|
||||||
HashSet proxyInterfaces = new HashSet();
|
HashSet proxyInterfaces = new HashSet();
|
||||||
proxyInterfaces.add( HibernateProxy.class );
|
proxyInterfaces.add( HibernateProxy.class );
|
||||||
|
@ -132,15 +154,73 @@ public class Dom4jEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
return pf;
|
return pf;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Class getMappedClass() {
|
public Class getMappedClass() {
|
||||||
return Element.class;
|
return Element.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Class getConcreteProxyClass() {
|
public Class getConcreteProxyClass() {
|
||||||
return Element.class;
|
return Element.class;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public boolean isInstrumented() {
|
public boolean isInstrumented() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public EntityNameResolver[] getEntityNameResolvers() {
|
||||||
|
return new EntityNameResolver[] { new BasicEntityNameResolver( getEntityName(), inheritenceNodeNameMap ) };
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
|
||||||
|
return ( String ) inheritenceNodeNameMap.get( extractNodeName( ( Element ) entityInstance ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String extractNodeName(Element element) {
|
||||||
|
return element.getName();
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BasicEntityNameResolver implements EntityNameResolver {
|
||||||
|
private final String rootEntityName;
|
||||||
|
private final Map nodeNameToEntityNameMap;
|
||||||
|
|
||||||
|
public BasicEntityNameResolver(String rootEntityName, Map nodeNameToEntityNameMap) {
|
||||||
|
this.rootEntityName = rootEntityName;
|
||||||
|
this.nodeNameToEntityNameMap = nodeNameToEntityNameMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String resolveEntityName(Object entity) {
|
||||||
|
return ( String ) nodeNameToEntityNameMap.get( extractNodeName( ( Element ) entity ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return rootEntityName.equals( ( ( BasicEntityNameResolver ) obj ).rootEntityName );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public int hashCode() {
|
||||||
|
return rootEntityName.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,6 +28,8 @@ import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
|
import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
import org.hibernate.tuple.Instantiator;
|
import org.hibernate.tuple.Instantiator;
|
||||||
import org.hibernate.tuple.DynamicMapInstantiator;
|
import org.hibernate.tuple.DynamicMapInstantiator;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
@ -112,4 +114,37 @@ public class DynamicMapEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
public boolean isInstrumented() {
|
public boolean isInstrumented() {
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityNameResolver[] getEntityNameResolvers() {
|
||||||
|
return new EntityNameResolver[] { BasicEntityNameResolver.INSTANCE };
|
||||||
|
}
|
||||||
|
|
||||||
|
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
|
||||||
|
// TODO : do we need an explicit isInstance check here, or is that asserted prior to here?
|
||||||
|
return extractEmbeddedEntityName( ( Map ) entityInstance );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String extractEmbeddedEntityName(Map entity) {
|
||||||
|
return ( String ) entity.get( DynamicMapInstantiator.KEY );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class BasicEntityNameResolver implements EntityNameResolver {
|
||||||
|
public static final BasicEntityNameResolver INSTANCE = new BasicEntityNameResolver();
|
||||||
|
|
||||||
|
public String resolveEntityName(Object entity) {
|
||||||
|
final String entityName = extractEmbeddedEntityName( ( Map ) entity );
|
||||||
|
if ( entityName == null ) {
|
||||||
|
throw new HibernateException( "Could not determine type of dynamic map entity" );
|
||||||
|
}
|
||||||
|
return entityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return getClass().equals( obj.getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return getClass().hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -122,21 +122,10 @@ public class EntityMetamodel implements Serializable {
|
||||||
private final boolean inherited;
|
private final boolean inherited;
|
||||||
private final boolean hasSubclasses;
|
private final boolean hasSubclasses;
|
||||||
private final Set subclassEntityNames = new HashSet();
|
private final Set subclassEntityNames = new HashSet();
|
||||||
|
private final Map entityNameByInheritenceClassNameMap = new HashMap();
|
||||||
|
|
||||||
private final EntityEntityModeToTuplizerMapping tuplizerMapping;
|
private final EntityEntityModeToTuplizerMapping tuplizerMapping;
|
||||||
|
|
||||||
public EntityTuplizer getTuplizer(EntityMode entityMode) {
|
|
||||||
return (EntityTuplizer) tuplizerMapping.getTuplizer( entityMode );
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
|
|
||||||
return ( EntityTuplizer ) tuplizerMapping.getTuplizerOrNull( entityMode );
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityMode guessEntityMode(Object object) {
|
|
||||||
return tuplizerMapping.guessEntityMode( object );
|
|
||||||
}
|
|
||||||
|
|
||||||
public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
|
public EntityMetamodel(PersistentClass persistentClass, SessionFactoryImplementor sessionFactory) {
|
||||||
this.sessionFactory = sessionFactory;
|
this.sessionFactory = sessionFactory;
|
||||||
|
|
||||||
|
@ -322,6 +311,15 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
subclassEntityNames.add( name );
|
subclassEntityNames.add( name );
|
||||||
|
|
||||||
|
if ( persistentClass.hasPojoRepresentation() ) {
|
||||||
|
entityNameByInheritenceClassNameMap.put( persistentClass.getMappedClass(), persistentClass.getEntityName() );
|
||||||
|
iter = persistentClass.getSubclassIterator();
|
||||||
|
while ( iter.hasNext() ) {
|
||||||
|
final PersistentClass pc = ( PersistentClass ) iter.next();
|
||||||
|
entityNameByInheritenceClassNameMap.put( pc.getMappedClass(), pc.getEntityName() );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
tuplizerMapping = new EntityEntityModeToTuplizerMapping( persistentClass, this );
|
tuplizerMapping = new EntityEntityModeToTuplizerMapping( persistentClass, this );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -395,6 +393,22 @@ public class EntityMetamodel implements Serializable {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public EntityEntityModeToTuplizerMapping getTuplizerMapping() {
|
||||||
|
return tuplizerMapping;
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityTuplizer getTuplizer(EntityMode entityMode) {
|
||||||
|
return (EntityTuplizer) tuplizerMapping.getTuplizer( entityMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityTuplizer getTuplizerOrNull(EntityMode entityMode) {
|
||||||
|
return ( EntityTuplizer ) tuplizerMapping.getTuplizerOrNull( entityMode );
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityMode guessEntityMode(Object object) {
|
||||||
|
return tuplizerMapping.guessEntityMode( object );
|
||||||
|
}
|
||||||
|
|
||||||
public int[] getNaturalIdentifierProperties() {
|
public int[] getNaturalIdentifierProperties() {
|
||||||
return naturalIdPropertyNumbers;
|
return naturalIdPropertyNumbers;
|
||||||
}
|
}
|
||||||
|
@ -555,6 +569,16 @@ public class EntityMetamodel implements Serializable {
|
||||||
return isAbstract;
|
return isAbstract;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Return the entity-name mapped to the given class within our inheritence hierarchy, if any.
|
||||||
|
*
|
||||||
|
* @param inheritenceClass The class for which to resolve the entity-name.
|
||||||
|
* @return The mapped entity-name, or null if no such mapping was found.
|
||||||
|
*/
|
||||||
|
public String findEntityNameByEntityClass(Class inheritenceClass) {
|
||||||
|
return ( String ) entityNameByInheritenceClassNameMap.get( inheritenceClass.getName() );
|
||||||
|
}
|
||||||
|
|
||||||
public String toString() {
|
public String toString() {
|
||||||
return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')';
|
return "EntityMetamodel(" + name + ':' + ArrayHelper.toString(properties) + ')';
|
||||||
}
|
}
|
||||||
|
|
|
@ -28,8 +28,11 @@ import java.io.Serializable;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
|
import org.hibernate.EntityMode;
|
||||||
import org.hibernate.tuple.Tuplizer;
|
import org.hibernate.tuple.Tuplizer;
|
||||||
import org.hibernate.engine.SessionImplementor;
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Defines further responsibilities reagarding tuplization based on
|
* Defines further responsibilities reagarding tuplization based on
|
||||||
|
@ -42,6 +45,12 @@ import org.hibernate.engine.SessionImplementor;
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
*/
|
*/
|
||||||
public interface EntityTuplizer extends Tuplizer {
|
public interface EntityTuplizer extends Tuplizer {
|
||||||
|
/**
|
||||||
|
* Return the entity-mode handled by this tuplizer instance.
|
||||||
|
*
|
||||||
|
* @return The entity-mode
|
||||||
|
*/
|
||||||
|
public EntityMode getEntityMode();
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create an entity instance initialized with the given identifier.
|
* Create an entity instance initialized with the given identifier.
|
||||||
|
@ -176,11 +185,11 @@ public interface EntityTuplizer extends Tuplizer {
|
||||||
*/
|
*/
|
||||||
public boolean isValidatableImplementor();
|
public boolean isValidatableImplementor();
|
||||||
|
|
||||||
// TODO: getConcreteProxyClass() is solely used (externally) to perform narrowProxy()
|
|
||||||
// would be great to fully encapsulate that narrowProxy() functionality within the
|
|
||||||
// Tuplizer, itself, with a Tuplizer.narrowProxy(..., PersistentContext) method
|
|
||||||
/**
|
/**
|
||||||
* Returns the java class to which generated proxies will be typed.
|
* Returns the java class to which generated proxies will be typed.
|
||||||
|
* <p/>
|
||||||
|
* todo : look at fully encapsulating {@link org.hibernate.engine.PersistenceContext#narrowProxy} here,
|
||||||
|
* since that is the only external use of this method
|
||||||
*
|
*
|
||||||
* @return The java class to which generated proxies will be typed
|
* @return The java class to which generated proxies will be typed
|
||||||
*/
|
*/
|
||||||
|
@ -198,4 +207,35 @@ public interface EntityTuplizer extends Tuplizer {
|
||||||
* Is it an instrumented POJO?
|
* Is it an instrumented POJO?
|
||||||
*/
|
*/
|
||||||
public boolean isInstrumented();
|
public boolean isInstrumented();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get any {@link EntityNameResolver EntityNameResolvers} associated with this {@link Tuplizer}.
|
||||||
|
*
|
||||||
|
* @return The associated resolvers. May be null or empty.
|
||||||
|
*/
|
||||||
|
public EntityNameResolver[] getEntityNameResolvers();
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given an entity instance, determine the most appropriate (most targeted) entity-name which represents it.
|
||||||
|
* This is called in situations where we already know an entity name for the given entityInstance; we are being
|
||||||
|
* asked to determine if there is a more appropriate entity-name to use, specifically within an inheritence
|
||||||
|
* hierarchy.
|
||||||
|
* <p/>
|
||||||
|
* For example, consider a case where a user calls <tt>session.update( "Animal", cat );</tt>. Here, the
|
||||||
|
* user has explicitly provided <tt>Animal</tt> as the entity-name. However, they have passed in an instance
|
||||||
|
* of <tt>Cat</tt> which is a subclass of <tt>Animal</tt>. In this case, we would return <tt>Cat</tt> as the
|
||||||
|
* entity-name.
|
||||||
|
* <p/>
|
||||||
|
* <tt>null</tt> may be returned from calls to this method. The meaining of <tt>null</tt> in that case is assumed
|
||||||
|
* to be that we should use whatever explicit entity-name the user provided (<tt>Animal</tt> rather than <tt>Cat</tt>
|
||||||
|
* in the example above).
|
||||||
|
*
|
||||||
|
* @param entityInstance The entity instance.
|
||||||
|
* @param factory Reference to the SessionFactory.
|
||||||
|
*
|
||||||
|
* @return The most appropriate entity name to use.
|
||||||
|
*
|
||||||
|
* @throws HibernateException If we are unable to determine an entity-name within the inheritence hierarchy.
|
||||||
|
*/
|
||||||
|
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory);
|
||||||
}
|
}
|
||||||
|
|
|
@ -36,6 +36,7 @@ import org.slf4j.LoggerFactory;
|
||||||
import org.hibernate.EntityMode;
|
import org.hibernate.EntityMode;
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.MappingException;
|
import org.hibernate.MappingException;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
import org.hibernate.tuple.Instantiator;
|
import org.hibernate.tuple.Instantiator;
|
||||||
import org.hibernate.tuple.PojoInstantiator;
|
import org.hibernate.tuple.PojoInstantiator;
|
||||||
import org.hibernate.bytecode.ReflectionOptimizer;
|
import org.hibernate.bytecode.ReflectionOptimizer;
|
||||||
|
@ -43,6 +44,7 @@ import org.hibernate.cfg.Environment;
|
||||||
import org.hibernate.classic.Lifecycle;
|
import org.hibernate.classic.Lifecycle;
|
||||||
import org.hibernate.classic.Validatable;
|
import org.hibernate.classic.Validatable;
|
||||||
import org.hibernate.engine.SessionImplementor;
|
import org.hibernate.engine.SessionImplementor;
|
||||||
|
import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
import org.hibernate.intercept.FieldInterceptor;
|
import org.hibernate.intercept.FieldInterceptor;
|
||||||
import org.hibernate.intercept.FieldInterceptionHelper;
|
import org.hibernate.intercept.FieldInterceptionHelper;
|
||||||
import org.hibernate.mapping.PersistentClass;
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
@ -70,7 +72,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
private final boolean lifecycleImplementor;
|
private final boolean lifecycleImplementor;
|
||||||
private final boolean validatableImplementor;
|
private final boolean validatableImplementor;
|
||||||
private final Set lazyPropertyNames = new HashSet();
|
private final Set lazyPropertyNames = new HashSet();
|
||||||
private ReflectionOptimizer optimizer;
|
private final ReflectionOptimizer optimizer;
|
||||||
|
|
||||||
public PojoEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
public PojoEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
||||||
super( entityMetamodel, mappedEntity );
|
super( entityMetamodel, mappedEntity );
|
||||||
|
@ -109,6 +111,9 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
||||||
// determine the id getter and setter methods from the proxy interface (if any)
|
// determine the id getter and setter methods from the proxy interface (if any)
|
||||||
// determine all interfaces needed by the resulting proxy
|
// determine all interfaces needed by the resulting proxy
|
||||||
|
@ -199,11 +204,14 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
|
|
||||||
protected ProxyFactory buildProxyFactoryInternal(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
protected ProxyFactory buildProxyFactoryInternal(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
||||||
// TODO : YUCK!!! finx after HHH-1907 is complete
|
// TODO : YUCK!!! fix after HHH-1907 is complete
|
||||||
return Environment.getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
|
return Environment.getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
|
||||||
// return getFactory().getSettings().getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
|
// return getFactory().getSettings().getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
||||||
if ( optimizer == null ) {
|
if ( optimizer == null ) {
|
||||||
return new PojoInstantiator( persistentClass, null );
|
return new PojoInstantiator( persistentClass, null );
|
||||||
|
@ -213,6 +221,9 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
|
public void setPropertyValues(Object entity, Object[] values) throws HibernateException {
|
||||||
if ( !getEntityMetamodel().hasLazyProperties() && optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
if ( !getEntityMetamodel().hasLazyProperties() && optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
||||||
setPropertyValuesWithOptimizer( entity, values );
|
setPropertyValuesWithOptimizer( entity, values );
|
||||||
|
@ -222,6 +233,9 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Object[] getPropertyValues(Object entity) throws HibernateException {
|
public Object[] getPropertyValues(Object entity) throws HibernateException {
|
||||||
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
||||||
return getPropertyValuesWithOptimizer( entity );
|
return getPropertyValuesWithOptimizer( entity );
|
||||||
|
@ -231,6 +245,9 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) throws HibernateException {
|
public Object[] getPropertyValuesToInsert(Object entity, Map mergeMap, SessionImplementor session) throws HibernateException {
|
||||||
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
if ( shouldGetAllProperties( entity ) && optimizer != null && optimizer.getAccessOptimizer() != null ) {
|
||||||
return getPropertyValuesWithOptimizer( entity );
|
return getPropertyValuesWithOptimizer( entity );
|
||||||
|
@ -248,36 +265,60 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
return optimizer.getAccessOptimizer().getPropertyValues( object );
|
return optimizer.getAccessOptimizer().getPropertyValues( object );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public EntityMode getEntityMode() {
|
public EntityMode getEntityMode() {
|
||||||
return EntityMode.POJO;
|
return EntityMode.POJO;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Class getMappedClass() {
|
public Class getMappedClass() {
|
||||||
return mappedClass;
|
return mappedClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public boolean isLifecycleImplementor() {
|
public boolean isLifecycleImplementor() {
|
||||||
return lifecycleImplementor;
|
return lifecycleImplementor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public boolean isValidatableImplementor() {
|
public boolean isValidatableImplementor() {
|
||||||
return validatableImplementor;
|
return validatableImplementor;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
|
protected Getter buildPropertyGetter(Property mappedProperty, PersistentClass mappedEntity) {
|
||||||
return mappedProperty.getGetter( mappedEntity.getMappedClass() );
|
return mappedProperty.getGetter( mappedEntity.getMappedClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
|
protected Setter buildPropertySetter(Property mappedProperty, PersistentClass mappedEntity) {
|
||||||
return mappedProperty.getSetter( mappedEntity.getMappedClass() );
|
return mappedProperty.getSetter( mappedEntity.getMappedClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public Class getConcreteProxyClass() {
|
public Class getConcreteProxyClass() {
|
||||||
return proxyInterface;
|
return proxyInterface;
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: need to make the majority of this functionality into a top-level support class for custom impl support
|
//TODO: need to make the majority of this functionality into a top-level support class for custom impl support
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
|
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
|
||||||
if ( isInstrumented() ) {
|
if ( isInstrumented() ) {
|
||||||
Set lazyProps = lazyPropertiesAreUnfetched && getEntityMetamodel().hasLazyProperties() ?
|
Set lazyProps = lazyPropertiesAreUnfetched && getEntityMetamodel().hasLazyProperties() ?
|
||||||
|
@ -288,6 +329,9 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public boolean hasUninitializedLazyProperties(Object entity) {
|
public boolean hasUninitializedLazyProperties(Object entity) {
|
||||||
if ( getEntityMetamodel().hasLazyProperties() ) {
|
if ( getEntityMetamodel().hasLazyProperties() ) {
|
||||||
FieldInterceptor callback = FieldInterceptionHelper.extractFieldInterceptor( entity );
|
FieldInterceptor callback = FieldInterceptionHelper.extractFieldInterceptor( entity );
|
||||||
|
@ -298,8 +342,37 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
public boolean isInstrumented() {
|
public boolean isInstrumented() {
|
||||||
return FieldInterceptionHelper.isInstrumented( getMappedClass() );
|
return FieldInterceptionHelper.isInstrumented( getMappedClass() );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
|
||||||
|
final Class concreteEntityClass = entityInstance.getClass();
|
||||||
|
if ( concreteEntityClass == getMappedClass() ) {
|
||||||
|
return getEntityName();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
String entityName = getEntityMetamodel().findEntityNameByEntityClass( concreteEntityClass );
|
||||||
|
if ( entityName == null ) {
|
||||||
|
throw new HibernateException(
|
||||||
|
"Unable to resolve entity name from Class [" + concreteEntityClass.getName() + "]"
|
||||||
|
+ " expected instance/subclass of [" + getEntityName() + "]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
return entityName;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@inheritDoc}
|
||||||
|
*/
|
||||||
|
public EntityNameResolver[] getEntityNameResolvers() {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?xml version="1.0"?>
|
||||||
|
<!--
|
||||||
|
~ Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
~
|
||||||
|
~ Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||||
|
~
|
||||||
|
~ 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
|
||||||
|
~
|
||||||
|
-->
|
||||||
|
|
||||||
|
<!DOCTYPE hibernate-mapping PUBLIC
|
||||||
|
"-//Hibernate/Hibernate Mapping DTD 3.0//EN"
|
||||||
|
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
|
||||||
|
|
||||||
|
<hibernate-mapping package="org.hibernate.test.dynamicentity">
|
||||||
|
|
||||||
|
<class name="Person" table="t_person" discriminator-value="person" abstract="false">
|
||||||
|
<tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
|
||||||
|
<id name="id">
|
||||||
|
<generator class="native"/>
|
||||||
|
</id>
|
||||||
|
<discriminator force="false"/>
|
||||||
|
<property name="name"/>
|
||||||
|
|
||||||
|
<many-to-one name="address" cascade="all" column="addr_id"/>
|
||||||
|
|
||||||
|
<set name="family" lazy="true" cascade="all">
|
||||||
|
<key column="pers_id"/>
|
||||||
|
<one-to-many class="Person"/>
|
||||||
|
</set>
|
||||||
|
|
||||||
|
<subclass name="Customer" discriminator-value="customer" abstract="false">
|
||||||
|
<tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
|
||||||
|
<many-to-one name="company" cascade="none" column="comp_id"/>
|
||||||
|
</subclass>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<class name="Company" table="t_company" abstract="false">
|
||||||
|
<tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
|
||||||
|
<id name="id">
|
||||||
|
<generator class="native"/>
|
||||||
|
</id>
|
||||||
|
<property name="name"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
<class name="Address" table="t_address" abstract="false">
|
||||||
|
<tuplizer class="org.hibernate.test.dynamicentity.tuplizer2.MyEntityTuplizer" entity-mode="pojo"/>
|
||||||
|
<id name="id">
|
||||||
|
<generator class="native"/>
|
||||||
|
</id>
|
||||||
|
<property name="street"/>
|
||||||
|
<property name="city"/>
|
||||||
|
<property name="postalCode"/>
|
||||||
|
</class>
|
||||||
|
|
||||||
|
</hibernate-mapping>
|
|
@ -0,0 +1,149 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||||
|
*
|
||||||
|
* 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.dynamicentity.tuplizer2;
|
||||||
|
|
||||||
|
import org.hibernate.test.dynamicentity.Company;
|
||||||
|
import org.hibernate.test.dynamicentity.ProxyHelper;
|
||||||
|
import org.hibernate.test.dynamicentity.Customer;
|
||||||
|
import org.hibernate.test.dynamicentity.Address;
|
||||||
|
import org.hibernate.test.dynamicentity.Person;
|
||||||
|
import org.hibernate.Session;
|
||||||
|
import org.hibernate.Hibernate;
|
||||||
|
import org.hibernate.cfg.Configuration;
|
||||||
|
import org.hibernate.junit.functional.FunctionalTestCase;
|
||||||
|
import org.hibernate.junit.functional.FunctionalTestClassTestSuite;
|
||||||
|
|
||||||
|
import junit.framework.TestSuite;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Demonstrates use of Tuplizers to allow the use of JDK
|
||||||
|
* {@link java.lang.reflect.Proxy dynamic proxies} as our
|
||||||
|
* domain model.
|
||||||
|
* <p/>
|
||||||
|
* Here we plug a custom Interceptor into the session simply to
|
||||||
|
* allow us to not have to explicitly supply the appropriate entity
|
||||||
|
* name to the Session calls.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class ImprovedTuplizerDynamicEntityTest extends FunctionalTestCase {
|
||||||
|
public ImprovedTuplizerDynamicEntityTest(String x) {
|
||||||
|
super( x );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String[] getMappings() {
|
||||||
|
return new String[] { "dynamicentity/tuplizer2/Customer.hbm.xml" };
|
||||||
|
}
|
||||||
|
|
||||||
|
public void configure(Configuration cfg) {
|
||||||
|
super.configure( cfg );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static TestSuite suite() {
|
||||||
|
return new FunctionalTestClassTestSuite( ImprovedTuplizerDynamicEntityTest.class );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void testIt() {
|
||||||
|
// Test saving these dyna-proxies
|
||||||
|
Session session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
Company company = ProxyHelper.newCompanyProxy();
|
||||||
|
company.setName( "acme" );
|
||||||
|
session.save( company );
|
||||||
|
Customer customer = ProxyHelper.newCustomerProxy();
|
||||||
|
customer.setName( "Steve" );
|
||||||
|
customer.setCompany( company );
|
||||||
|
Address address = ProxyHelper.newAddressProxy();
|
||||||
|
address.setStreet( "somewhere over the rainbow" );
|
||||||
|
address.setCity( "lawerence, kansas" );
|
||||||
|
address.setPostalCode( "toto");
|
||||||
|
customer.setAddress( address );
|
||||||
|
customer.setFamily( new HashSet() );
|
||||||
|
Person son = ProxyHelper.newPersonProxy();
|
||||||
|
son.setName( "son" );
|
||||||
|
customer.getFamily().add( son );
|
||||||
|
Person wife = ProxyHelper.newPersonProxy();
|
||||||
|
wife.setName( "wife" );
|
||||||
|
customer.getFamily().add( wife );
|
||||||
|
session.save( customer );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
assertNotNull( "company id not assigned", company.getId() );
|
||||||
|
assertNotNull( "customer id not assigned", customer.getId() );
|
||||||
|
assertNotNull( "address id not assigned", address.getId() );
|
||||||
|
assertNotNull( "son:Person id not assigned", son.getId() );
|
||||||
|
assertNotNull( "wife:Person id not assigned", wife.getId() );
|
||||||
|
|
||||||
|
// Test loading these dyna-proxies, along with flush processing
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
customer = ( Customer ) session.load( Customer.class, customer.getId() );
|
||||||
|
assertFalse( "should-be-proxy was initialized", Hibernate.isInitialized( customer ) );
|
||||||
|
|
||||||
|
customer.setName( "other" );
|
||||||
|
session.flush();
|
||||||
|
assertFalse( "should-be-proxy was initialized", Hibernate.isInitialized( customer.getCompany() ) );
|
||||||
|
|
||||||
|
session.refresh( customer );
|
||||||
|
assertEquals( "name not updated", "other", customer.getName() );
|
||||||
|
assertEquals( "company association not correct", "acme", customer.getCompany().getName() );
|
||||||
|
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
// Test detached entity re-attachment with these dyna-proxies
|
||||||
|
customer.setName( "Steve" );
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.update( customer );
|
||||||
|
session.flush();
|
||||||
|
session.refresh( customer );
|
||||||
|
assertEquals( "name not updated", "Steve", customer.getName() );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
// Test querying
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
int count = session.createQuery( "from Customer" ).list().size();
|
||||||
|
assertEquals( "querying dynamic entity", 1, count );
|
||||||
|
session.clear();
|
||||||
|
count = session.createQuery( "from Person" ).list().size();
|
||||||
|
assertEquals( "querying dynamic entity", 3, count );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
|
||||||
|
// test deleteing
|
||||||
|
session = openSession();
|
||||||
|
session.beginTransaction();
|
||||||
|
session.delete( company );
|
||||||
|
session.delete( customer );
|
||||||
|
session.getTransaction().commit();
|
||||||
|
session.close();
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,78 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||||
|
*
|
||||||
|
* 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.dynamicentity.tuplizer2;
|
||||||
|
|
||||||
|
import org.hibernate.tuple.Instantiator;
|
||||||
|
import org.hibernate.test.dynamicentity.Customer;
|
||||||
|
import org.hibernate.test.dynamicentity.ProxyHelper;
|
||||||
|
import org.hibernate.test.dynamicentity.Company;
|
||||||
|
import org.hibernate.test.dynamicentity.Address;
|
||||||
|
import org.hibernate.test.dynamicentity.Person;
|
||||||
|
import org.hibernate.util.ReflectHelper;
|
||||||
|
import org.hibernate.HibernateException;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class MyEntityInstantiator implements Instantiator {
|
||||||
|
private final String entityName;
|
||||||
|
|
||||||
|
public MyEntityInstantiator(String entityName) {
|
||||||
|
this.entityName = entityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object instantiate(Serializable id) {
|
||||||
|
if ( Person.class.getName().equals( entityName ) ) {
|
||||||
|
return ProxyHelper.newPersonProxy( id );
|
||||||
|
}
|
||||||
|
if ( Customer.class.getName().equals( entityName ) ) {
|
||||||
|
return ProxyHelper.newCustomerProxy( id );
|
||||||
|
}
|
||||||
|
else if ( Company.class.getName().equals( entityName ) ) {
|
||||||
|
return ProxyHelper.newCompanyProxy( id );
|
||||||
|
}
|
||||||
|
else if ( Address.class.getName().equals( entityName ) ) {
|
||||||
|
return ProxyHelper.newAddressProxy( id );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw new IllegalArgumentException( "unknown entity for instantiation [" + entityName + "]" );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public Object instantiate() {
|
||||||
|
return instantiate( null );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isInstance(Object object) {
|
||||||
|
try {
|
||||||
|
return ReflectHelper.classForName( entityName ).isInstance( object );
|
||||||
|
}
|
||||||
|
catch( Throwable t ) {
|
||||||
|
throw new HibernateException( "could not get handle to entity-name as interface : " + t );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,87 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* Copyright (c) 2008, Red Hat Middleware LLC 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 Middleware LLC.
|
||||||
|
*
|
||||||
|
* 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.dynamicentity.tuplizer2;
|
||||||
|
|
||||||
|
import org.hibernate.tuple.entity.PojoEntityTuplizer;
|
||||||
|
import org.hibernate.tuple.entity.EntityMetamodel;
|
||||||
|
import org.hibernate.tuple.Instantiator;
|
||||||
|
import org.hibernate.mapping.PersistentClass;
|
||||||
|
import org.hibernate.proxy.ProxyFactory;
|
||||||
|
import org.hibernate.property.Getter;
|
||||||
|
import org.hibernate.property.Setter;
|
||||||
|
import org.hibernate.test.dynamicentity.tuplizer.MyEntityInstantiator;
|
||||||
|
import org.hibernate.test.dynamicentity.ProxyHelper;
|
||||||
|
import org.hibernate.engine.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.EntityNameResolver;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class MyEntityTuplizer extends PojoEntityTuplizer {
|
||||||
|
|
||||||
|
public MyEntityTuplizer(EntityMetamodel entityMetamodel, PersistentClass mappedEntity) {
|
||||||
|
super( entityMetamodel, mappedEntity );
|
||||||
|
}
|
||||||
|
|
||||||
|
public EntityNameResolver[] getEntityNameResolvers() {
|
||||||
|
return new EntityNameResolver[] { MyEntityNameResolver.INSTANCE };
|
||||||
|
}
|
||||||
|
|
||||||
|
protected Instantiator buildInstantiator(PersistentClass persistentClass) {
|
||||||
|
return new MyEntityInstantiator( persistentClass.getEntityName() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
|
||||||
|
String entityName = ProxyHelper.extractEntityName( entityInstance );
|
||||||
|
if ( entityName == null ) {
|
||||||
|
entityName = super.determineConcreteSubclassEntityName( entityInstance, factory );
|
||||||
|
}
|
||||||
|
return entityName;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected ProxyFactory buildProxyFactory(PersistentClass persistentClass, Getter idGetter, Setter idSetter) {
|
||||||
|
// allows defining a custom proxy factory, which is responsible for
|
||||||
|
// generating lazy proxies for a given entity.
|
||||||
|
//
|
||||||
|
// Here we simply use the default...
|
||||||
|
return super.buildProxyFactory( persistentClass, idGetter, idSetter );
|
||||||
|
}
|
||||||
|
|
||||||
|
public static class MyEntityNameResolver implements EntityNameResolver {
|
||||||
|
public static final MyEntityNameResolver INSTANCE = new MyEntityNameResolver();
|
||||||
|
|
||||||
|
public String resolveEntityName(Object entity) {
|
||||||
|
return ProxyHelper.extractEntityName( entity );
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean equals(Object obj) {
|
||||||
|
return getClass().equals( obj.getClass() );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int hashCode() {
|
||||||
|
return getClass().hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue