HHH-7919 : Miscellaneous bugfixes

This commit is contained in:
Strong Liu 2013-07-18 14:14:11 +08:00
parent b1312381b1
commit c9738beaf4
4 changed files with 43 additions and 123 deletions

View File

@ -26,15 +26,14 @@ package org.hibernate.bytecode.internal.javassist;
import java.lang.reflect.Method; import java.lang.reflect.Method;
import java.util.HashMap; import java.util.HashMap;
import javassist.util.proxy.MethodFilter;
import javassist.util.proxy.MethodHandler; import javassist.util.proxy.MethodHandler;
import javassist.util.proxy.ProxyObject; import javassist.util.proxy.ProxyObject;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.bytecode.spi.BasicProxyFactory; import org.hibernate.bytecode.spi.BasicProxyFactory;
import org.hibernate.bytecode.spi.ProxyFactoryFactory; import org.hibernate.bytecode.spi.ProxyFactoryFactory;
import org.hibernate.proxy.ProxyFactory; import org.hibernate.proxy.ProxyFactory;
import org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer;
import org.hibernate.proxy.pojo.javassist.JavassistProxyFactory; import org.hibernate.proxy.pojo.javassist.JavassistProxyFactory;
/** /**
@ -69,19 +68,7 @@ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
private final Class proxyClass; private final Class proxyClass;
public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) { public BasicProxyFactoryImpl(Class superClass, Class[] interfaces) {
if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) { proxyClass = JavassistLazyInitializer.getProxyFactory( superClass, interfaces );
throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
}
final javassist.util.proxy.ProxyFactory factory = new javassist.util.proxy.ProxyFactory();
factory.setFilter( FINALIZE_FILTER );
if ( superClass != null ) {
factory.setSuperclass( superClass );
}
if ( interfaces != null && interfaces.length > 0 ) {
factory.setInterfaces( interfaces );
}
proxyClass = factory.createClass();
} }
public Object getProxy() { public Object getProxy() {
@ -100,12 +87,6 @@ public class ProxyFactoryFactoryImpl implements ProxyFactoryFactory {
} }
} }
private static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
public boolean isHandled(Method m) {
// skip finalize methods
return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
}
};
private static class PassThroughHandler implements MethodHandler { private static class PassThroughHandler implements MethodHandler {
private HashMap data = new HashMap(); private HashMap data = new HashMap();

View File

@ -33,6 +33,7 @@ import javassist.util.proxy.ProxyFactory;
import javassist.util.proxy.ProxyObject; import javassist.util.proxy.ProxyObject;
import org.jboss.logging.Logger; import org.jboss.logging.Logger;
import org.hibernate.AssertionFailure;
import org.hibernate.HibernateException; import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor; import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.internal.CoreMessageLogger; import org.hibernate.internal.CoreMessageLogger;
@ -50,7 +51,8 @@ public class JavassistLazyInitializer extends BasicLazyInitializer implements Me
private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, JavassistLazyInitializer.class.getName()); private static final CoreMessageLogger LOG = Logger.getMessageLogger(CoreMessageLogger.class, JavassistLazyInitializer.class.getName());
private static final MethodFilter FINALIZE_FILTER = new MethodFilter() { public static final MethodFilter FINALIZE_FILTER = new MethodFilter() {
@Override
public boolean isHandled(Method m) { public boolean isHandled(Method m) {
// skip finalize methods // skip finalize methods
return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) ); return !( m.getParameterTypes().length == 0 && m.getName().equals( "finalize" ) );
@ -75,41 +77,22 @@ public class JavassistLazyInitializer extends BasicLazyInitializer implements Me
} }
public static HibernateProxy getProxy( public static HibernateProxy getProxy(
final String entityName, final String entityName, final Class persistentClass, final Class[] interfaces,
final Class persistentClass, final Method getIdentifierMethod, final Method setIdentifierMethod, CompositeType componentIdType,
final Class[] interfaces, final Serializable id, final SessionImplementor session) throws HibernateException {
final Method getIdentifierMethod,
final Method setIdentifierMethod, return getProxy(
CompositeType componentIdType, getProxyFactory( persistentClass, interfaces ),
final Serializable id,
final SessionImplementor session) throws HibernateException {
// note: interface is assumed to already contain HibernateProxy.class
try {
final JavassistLazyInitializer instance = new JavassistLazyInitializer(
entityName, entityName,
persistentClass, persistentClass,
interfaces, interfaces,
id,
getIdentifierMethod, getIdentifierMethod,
setIdentifierMethod, setIdentifierMethod,
componentIdType, componentIdType,
id,
session, session,
ReflectHelper.overridesEquals(persistentClass) ReflectHelper.overridesEquals( persistentClass )
); );
ProxyFactory factory = new ProxyFactory();
factory.setSuperclass( interfaces.length == 1 ? persistentClass : null );
factory.setInterfaces( interfaces );
factory.setFilter( FINALIZE_FILTER );
Class cl = factory.createClass();
final HibernateProxy proxy = ( HibernateProxy ) cl.newInstance();
( ( ProxyObject ) proxy ).setHandler( instance );
instance.constructed = true;
return proxy;
}
catch ( Throwable t ) {
LOG.error(LOG.javassistEnhancementFailed(entityName), t);
throw new HibernateException(LOG.javassistEnhancementFailed(entityName), t);
}
} }
public static HibernateProxy getProxy( public static HibernateProxy getProxy(
@ -127,7 +110,8 @@ public class JavassistLazyInitializer extends BasicLazyInitializer implements Me
final JavassistLazyInitializer instance = new JavassistLazyInitializer( final JavassistLazyInitializer instance = new JavassistLazyInitializer(
entityName, entityName,
persistentClass, persistentClass,
interfaces, id, interfaces,
id,
getIdentifierMethod, getIdentifierMethod,
setIdentifierMethod, setIdentifierMethod,
componentIdType, componentIdType,
@ -151,20 +135,23 @@ public class JavassistLazyInitializer extends BasicLazyInitializer implements Me
} }
public static Class getProxyFactory( public static Class getProxyFactory(
Class persistentClass, Class superClass, Class[] interfaces) throws HibernateException {
Class[] interfaces) throws HibernateException {
// note: interfaces is assumed to already contain HibernateProxy.class // note: interfaces is assumed to already contain HibernateProxy.class
if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
}
try { try {
ProxyFactory factory = new ProxyFactory(); ProxyFactory factory = new ProxyFactory();
factory.setSuperclass( interfaces.length == 1 ? persistentClass : null ); factory.setSuperclass( interfaces.length == 1 ? superClass : null );
factory.setInterfaces( interfaces ); factory.setInterfaces( interfaces );
factory.setFilter( FINALIZE_FILTER ); factory.setFilter( FINALIZE_FILTER );
return factory.createClass(); return factory.createClass();
} }
catch ( Throwable t ) { catch ( Throwable t ) {
LOG.error(LOG.javassistEnhancementFailed(persistentClass.getName()), t); Class caculatedSuperClass = superClass != null ? superClass : interfaces[0];
throw new HibernateException(LOG.javassistEnhancementFailed(persistentClass.getName()), t); LOG.error( LOG.javassistEnhancementFailed( caculatedSuperClass.getName() ), t );
throw new HibernateException( LOG.javassistEnhancementFailed( caculatedSuperClass.getName() ), t );
} }
} }

View File

@ -40,7 +40,6 @@ import org.hibernate.type.CompositeType;
*/ */
public class JavassistProxyFactory implements ProxyFactory, Serializable { public class JavassistProxyFactory implements ProxyFactory, Serializable {
protected static final Class[] NO_CLASSES = new Class[0];
private Class persistentClass; private Class persistentClass;
private String entityName; private String entityName;
private Class[] interfaces; private Class[] interfaces;
@ -60,7 +59,7 @@ public class JavassistProxyFactory implements ProxyFactory, Serializable {
CompositeType componentIdType) throws HibernateException { CompositeType componentIdType) throws HibernateException {
this.entityName = entityName; this.entityName = entityName;
this.persistentClass = persistentClass; this.persistentClass = persistentClass;
this.interfaces = interfaces.toArray(NO_CLASSES); this.interfaces = interfaces.toArray( new Class[interfaces.size()] );
this.getIdentifierMethod = getIdentifierMethod; this.getIdentifierMethod = getIdentifierMethod;
this.setIdentifierMethod = setIdentifierMethod; this.setIdentifierMethod = setIdentifierMethod;
this.componentIdType = componentIdType; this.componentIdType = componentIdType;

View File

@ -27,6 +27,7 @@ import java.lang.reflect.Method;
import java.lang.reflect.Modifier; import java.lang.reflect.Modifier;
import java.util.HashSet; import java.util.HashSet;
import java.util.Iterator; import java.util.Iterator;
import java.util.LinkedHashSet;
import java.util.Map; import java.util.Map;
import java.util.Set; import java.util.Set;
@ -151,9 +152,6 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
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)
@ -250,9 +248,6 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
// return getFactory().getSettings().getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory(); // return getFactory().getSettings().getBytecodeProvider().getProxyFactoryFactory().buildProxyFactory();
} }
/**
* {@inheritDoc}
*/
@Override @Override
protected Instantiator buildInstantiator(PersistentClass persistentClass) { protected Instantiator buildInstantiator(PersistentClass persistentClass) {
if ( optimizer == null ) { if ( optimizer == null ) {
@ -263,18 +258,16 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
protected ProxyFactory buildProxyFactory(EntityBinding entityBinding, Getter idGetter, Setter idSetter) { protected ProxyFactory buildProxyFactory(EntityBinding entityBinding, 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
HashSet<Class> proxyInterfaces = new HashSet<Class>(); HashSet<Class> proxyInterfaces = new LinkedHashSet<Class>();
proxyInterfaces.add( HibernateProxy.class );
Class mappedClass = entityBinding.getEntity().getClassReference(); Class mappedClass = entityBinding.getEntity().getClassReference();
Class proxyInterface = entityBinding.getProxyInterfaceType().getValue(); Class proxyInterface = entityBinding.getProxyInterfaceType() == null ? null : entityBinding.getProxyInterfaceType()
.getValue();
if ( proxyInterface!=null && !mappedClass.equals( proxyInterface ) ) { if ( proxyInterface!=null && !mappedClass.equals( proxyInterface ) ) {
if ( ! proxyInterface.isInterface() ) { if ( ! proxyInterface.isInterface() ) {
@ -288,7 +281,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
if ( mappedClass.isInterface() ) { if ( mappedClass.isInterface() ) {
proxyInterfaces.add( mappedClass ); proxyInterfaces.add( mappedClass );
} }
proxyInterfaces.add( HibernateProxy.class ); // we add the HibernateProxy.clas to the last of the set
for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) { for ( EntityBinding subEntityBinding : entityBinding.getPostOrderSubEntityBindingClosure() ) {
final Class subclassProxy = subEntityBinding.getProxyInterfaceType().getValue(); final Class subclassProxy = subEntityBinding.getProxyInterfaceType().getValue();
final Class subclassClass = subEntityBinding.getClassReference(); final Class subclassClass = subEntityBinding.getClassReference();
@ -379,9 +372,6 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
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 ) {
@ -392,9 +382,6 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
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 ) {
@ -413,72 +400,47 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
return optimizer.getAccessOptimizer().getPropertyValues( object ); return optimizer.getAccessOptimizer().getPropertyValues( object );
} }
/** @Override
* {@inheritDoc}
*/
public EntityMode getEntityMode() { public EntityMode getEntityMode() {
return EntityMode.POJO; return EntityMode.POJO;
} }
/** @Override
* {@inheritDoc}
*/
public Class getMappedClass() { public Class getMappedClass() {
return mappedClass; return mappedClass;
} }
/**
* {@inheritDoc}
*/
@Override @Override
public boolean isLifecycleImplementor() { public boolean isLifecycleImplementor() {
return lifecycleImplementor; return lifecycleImplementor;
} }
/**
* {@inheritDoc}
*/
@Override @Override
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}
*/
@Override @Override
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}
*/
@Override @Override
protected Getter buildPropertyGetter(AttributeBinding mappedProperty) { protected Getter buildPropertyGetter(AttributeBinding mappedProperty) {
return PropertyFactory.getGetter( mappedProperty ); return PropertyFactory.getGetter( mappedProperty );
} }
/**
* {@inheritDoc}
*/
@Override @Override
protected Setter buildPropertySetter(AttributeBinding mappedProperty) { protected Setter buildPropertySetter(AttributeBinding mappedProperty) {
return PropertyFactory.getSetter( mappedProperty ); return PropertyFactory.getSetter( mappedProperty );
} }
/**
* {@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}
*/
@Override @Override
public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) { public void afterInitialize(Object entity, boolean lazyPropertiesAreUnfetched, SessionImplementor session) {
if ( isInstrumented() ) { if ( isInstrumented() ) {
@ -490,9 +452,6 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
} }
/**
* {@inheritDoc}
*/
@Override @Override
public boolean hasUninitializedLazyProperties(Object entity) { public boolean hasUninitializedLazyProperties(Object entity) {
if ( getEntityMetamodel().hasLazyProperties() ) { if ( getEntityMetamodel().hasLazyProperties() ) {
@ -504,16 +463,12 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
} }
/** @Override
* {@inheritDoc}
*/
public boolean isInstrumented() { public boolean isInstrumented() {
return isInstrumented; return isInstrumented;
} }
/** @Override
* {@inheritDoc}
*/
public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) { public String determineConcreteSubclassEntityName(Object entityInstance, SessionFactoryImplementor factory) {
final Class concreteEntityClass = entityInstance.getClass(); final Class concreteEntityClass = entityInstance.getClass();
if ( concreteEntityClass == getMappedClass() ) { if ( concreteEntityClass == getMappedClass() ) {
@ -531,9 +486,7 @@ public class PojoEntityTuplizer extends AbstractEntityTuplizer {
} }
} }
/** @Override
* {@inheritDoc}
*/
public EntityNameResolver[] getEntityNameResolvers() { public EntityNameResolver[] getEntityNameResolvers() {
return null; return null;
} }