HHH-10202 : Delay resolving TypeScopeImpl#factory after deserialization until resolveFactory() is called.

This commit is contained in:
Gail Badner 2015-11-03 14:30:27 -08:00
parent bec5ee854c
commit ac49051add
3 changed files with 80 additions and 42 deletions

View File

@ -271,6 +271,15 @@ public final class SessionFactoryImpl
this.observer.addObserver( observer );
}
// name and uuid must be initialized before scoping the TypeResolver to this object.
name = settings.getSessionFactoryName();
try {
uuid = (String) UUID_GENERATOR.generate(null, null);
}
catch (Exception e) {
throw new AssertionFailure("Could not generate UUID");
}
this.typeResolver = cfg.getTypeResolver().scope( this );
this.typeHelper = new TypeLocatorImpl( typeResolver );
@ -474,13 +483,6 @@ public final class SessionFactoryImpl
//JNDI + Serialization:
name = settings.getSessionFactoryName();
try {
uuid = (String) UUID_GENERATOR.generate(null, null);
}
catch (Exception e) {
throw new AssertionFailure("Could not generate UUID");
}
SessionFactoryRegistry.INSTANCE.addSessionFactory(
uuid,
name,
@ -693,6 +695,15 @@ public final class SessionFactoryImpl
this.observer.addObserver( observer );
}
// name and uuid must be initialized before scoping the TypeResolver to this object.
name = settings.getSessionFactoryName();
try {
uuid = (String) UUID_GENERATOR.generate(null, null);
}
catch (Exception e) {
throw new AssertionFailure("Could not generate UUID");
}
this.typeResolver = metadata.getTypeResolver().scope( this );
this.typeHelper = new TypeLocatorImpl( typeResolver );
@ -883,13 +894,6 @@ public final class SessionFactoryImpl
//JNDI + Serialization:
name = settings.getSessionFactoryName();
try {
uuid = (String) UUID_GENERATOR.generate(null, null);
}
catch (Exception e) {
throw new AssertionFailure("Could not generate UUID");
}
SessionFactoryRegistry.INSTANCE.addSessionFactory(
uuid,
name,

View File

@ -27,14 +27,16 @@ import java.io.Serializable;
import java.util.Comparator;
import java.util.Properties;
import javax.naming.NamingException;
import org.hibernate.HibernateException;
import org.hibernate.MappingException;
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
import org.hibernate.classic.Lifecycle;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.CoreMessageLogger;
import org.hibernate.internal.SessionFactoryRegistry;
import org.hibernate.internal.util.ReflectHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.tuple.component.ComponentMetamodel;
import org.hibernate.usertype.CompositeUserType;
import org.hibernate.usertype.ParameterizedType;
@ -73,26 +75,33 @@ public final class TypeFactory implements Serializable {
}
else {
LOG.tracev( "Scoping types to session factory {0}", factory );
sessionFactoryUuid = factory.getUuid();
String sfName = factory.getSettings().getSessionFactoryName();
if ( sfName == null ) {
final CfgXmlAccessService cfgXmlAccessService = factory.getServiceRegistry()
.getService( CfgXmlAccessService.class );
if ( cfgXmlAccessService.getAggregatedConfig() != null ) {
sfName = cfgXmlAccessService.getAggregatedConfig().getSessionFactoryName();
}
try {
sessionFactoryUuid = (String) factory.getReference().get( "uuid" ).getContent() ;
}
sessionFactoryName = sfName;
catch (NamingException ex) {
throw new HibernateException(
"Could not inject SessionFactory because UUID could not be determined.",
ex
);
}
if ( sessionFactoryUuid == null ) {
throw new IllegalArgumentException( "SessionFactory has null uuid." );
}
sessionFactoryName = factory.getSettings().getSessionFactoryName();
}
this.factory = factory;
}
public SessionFactoryImplementor resolveFactory() {
if ( factory == null ) {
factory = (SessionFactoryImplementor) SessionFactoryRegistry.INSTANCE.findSessionFactory(
sessionFactoryUuid,
sessionFactoryName
factory = (SessionFactoryImplementor) SessionFactoryRegistry.INSTANCE.getSessionFactory(
sessionFactoryUuid
);
if ( factory == null && StringHelper.isNotEmpty( sessionFactoryName ) ) {
factory = (SessionFactoryImplementor) SessionFactoryRegistry.INSTANCE.getNamedSessionFactory(
sessionFactoryName
);
}
if ( factory == null ) {
throw new HibernateException(
"Could not find a SessionFactory [uuid=" + sessionFactoryUuid + ",name=" + sessionFactoryName + "]"

View File

@ -6,14 +6,18 @@
*/
package org.hibernate.test.serialization;
import javax.naming.NamingException;
import org.junit.Test;
import org.hibernate.HibernateException;
import org.hibernate.SessionFactory;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Configuration;
import org.hibernate.engine.spi.SessionFactoryImplementor;
import org.hibernate.internal.SessionFactoryRegistry;
import org.hibernate.internal.util.SerializationHelper;
import org.hibernate.internal.util.StringHelper;
import org.hibernate.testing.junit4.BaseUnitTestCase;
import org.hibernate.type.TypeFactory;
@ -55,8 +59,8 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
assertSame( factory, SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( NAME ) );
// Remove the session factory from the registry
SessionFactoryRegistry.INSTANCE.removeSessionFactory( factory.getUuid(), NAME, false, null );
assertNull( SessionFactoryRegistry.INSTANCE.findSessionFactory( factory.getUuid(), NAME ) );
SessionFactoryRegistry.INSTANCE.removeSessionFactory( getSessionFactoryUuid( factory ), NAME, false, null );
assertNull( findSessionFactory( getSessionFactoryUuid( factory ), NAME ) );
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
@ -71,7 +75,7 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
}
// Re-register the same session factory.
SessionFactoryRegistry.INSTANCE.addSessionFactory( factory.getUuid(), NAME, false, factory, null );
SessionFactoryRegistry.INSTANCE.addSessionFactory( getSessionFactoryUuid( factory ), NAME, false, factory, null );
// Session factory resolved from typeFactory should be the new session factory
// (because it is resolved from SessionFactoryRegistry.INSTANCE)
@ -83,11 +87,11 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
public void testUnregisterSerializeRegisterSameSessionFactoryNoName() throws Exception {
Configuration cfg = new Configuration();
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
assertSame( factory, SessionFactoryRegistry.INSTANCE.findSessionFactory( factory.getUuid(), null ) );
assertSame( factory, findSessionFactory( getSessionFactoryUuid( factory ), null ) );
// Remove the session factory from the registry
SessionFactoryRegistry.INSTANCE.removeSessionFactory( factory.getUuid(), null, false, null );
assertNull( SessionFactoryRegistry.INSTANCE.findSessionFactory( factory.getUuid(), null ) );
SessionFactoryRegistry.INSTANCE.removeSessionFactory( getSessionFactoryUuid( factory ), null, false, null );
assertNull( findSessionFactory( getSessionFactoryUuid( factory ), null ) );
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
@ -102,7 +106,7 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
}
// Re-register the same session factory.
SessionFactoryRegistry.INSTANCE.addSessionFactory( factory.getUuid(), null, false, factory, null );
SessionFactoryRegistry.INSTANCE.addSessionFactory( getSessionFactoryUuid( factory), null, false, factory, null );
// Session factory resolved from typeFactory should be the new session factory
// (because it is resolved from SessionFactoryRegistry.INSTANCE)
@ -119,8 +123,8 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
assertSame( factory, SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( NAME ) );
// Remove the session factory from the registry
SessionFactoryRegistry.INSTANCE.removeSessionFactory( factory.getUuid(), NAME, false, null );
assertNull( SessionFactoryRegistry.INSTANCE.findSessionFactory( factory.getUuid(), NAME ) );
SessionFactoryRegistry.INSTANCE.removeSessionFactory( getSessionFactoryUuid( factory ), NAME, false, null );
assertNull( findSessionFactory( getSessionFactoryUuid( factory ), NAME ) );
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
@ -137,7 +141,7 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
// Now create a new session factory with the same name; it will have a different UUID.
SessionFactoryImplementor factoryWithSameName = (SessionFactoryImplementor) cfg.buildSessionFactory();
assertSame( factoryWithSameName, SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( NAME ) );
assertFalse( factory.getUuid().equals( factoryWithSameName.getUuid() ) );
assertFalse( getSessionFactoryUuid( factory ).equals( getSessionFactoryUuid( factoryWithSameName ) ) );
// Session factory resolved from typeFactory should be the new session factory
// (because it is resolved from SessionFactoryRegistry.INSTANCE)
@ -151,11 +155,11 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
public void testUnregisterSerializeRegisterDiffSessionFactoryNoName() throws Exception {
Configuration cfg = new Configuration();
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
assertSame( factory, SessionFactoryRegistry.INSTANCE.getSessionFactory( factory.getUuid() ) );
assertSame( factory, SessionFactoryRegistry.INSTANCE.getSessionFactory( getSessionFactoryUuid( factory ) ) );
// Remove the session factory from the registry
SessionFactoryRegistry.INSTANCE.removeSessionFactory( factory.getUuid(), null, false, null );
assertNull( SessionFactoryRegistry.INSTANCE.getSessionFactory( factory.getUuid() ) );
SessionFactoryRegistry.INSTANCE.removeSessionFactory( getSessionFactoryUuid( factory ), null, false, null );
assertNull( SessionFactoryRegistry.INSTANCE.getSessionFactory( getSessionFactoryUuid( factory ) ) );
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
@ -171,8 +175,8 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
// Now create a new session factory with the same name; it will have a different UUID.
SessionFactoryImplementor factoryWithDiffUuid = (SessionFactoryImplementor) cfg.buildSessionFactory();
assertSame( factoryWithDiffUuid, SessionFactoryRegistry.INSTANCE.getSessionFactory( factoryWithDiffUuid.getUuid() ) );
assertFalse( factory.getUuid().equals( factoryWithDiffUuid.getUuid() ) );
assertSame( factoryWithDiffUuid, SessionFactoryRegistry.INSTANCE.getSessionFactory( getSessionFactoryUuid( factoryWithDiffUuid ) ) );
assertFalse( getSessionFactoryUuid( factory ).equals( getSessionFactoryUuid( factoryWithDiffUuid ) ) );
// It should not be possible to resolve the session factory with no name configured.
try {
@ -186,4 +190,25 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
factory.close();
factoryWithDiffUuid.close();
}
private static String getSessionFactoryUuid(SessionFactory sessionFactory) throws NamingException {
try {
return (String) sessionFactory.getReference().get( "uuid" ).getContent() ;
}
catch (NamingException ex) {
throw new HibernateException(
"Could not determine UUID.",
ex
);
}
}
private static SessionFactory findSessionFactory(String uuid, String name ) {
SessionFactory sessionFactory = SessionFactoryRegistry.INSTANCE.getSessionFactory( uuid );
if ( sessionFactory == null && StringHelper.isNotEmpty( name ) ) {
sessionFactory = SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( name );
}
return sessionFactory;
}
}