HHH-12443 - Introduce TypeConfiguration
This commit is contained in:
parent
6721005208
commit
b228a2bc83
|
@ -48,6 +48,7 @@ import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||||
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
|
import org.hibernate.hql.spi.id.MultiTableBulkIdStrategy;
|
||||||
import org.hibernate.id.IdentifierGenerator;
|
import org.hibernate.id.IdentifierGenerator;
|
||||||
import org.hibernate.id.UUIDGenerator;
|
import org.hibernate.id.UUIDGenerator;
|
||||||
|
import org.hibernate.id.uuid.LocalObjectUuidHelper;
|
||||||
import org.hibernate.internal.log.DeprecationLogger;
|
import org.hibernate.internal.log.DeprecationLogger;
|
||||||
import org.hibernate.internal.util.config.ConfigurationHelper;
|
import org.hibernate.internal.util.config.ConfigurationHelper;
|
||||||
import org.hibernate.jpa.JpaCompliance;
|
import org.hibernate.jpa.JpaCompliance;
|
||||||
|
@ -240,12 +241,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
||||||
this.serviceRegistry = serviceRegistry;
|
this.serviceRegistry = serviceRegistry;
|
||||||
this.jpaBootstrap = context.isJpaBootstrap();
|
this.jpaBootstrap = context.isJpaBootstrap();
|
||||||
|
|
||||||
try {
|
this.uuid = LocalObjectUuidHelper.generateLocalObjectUuid();
|
||||||
uuid = (String) UUID_GENERATOR.generate( null, null );
|
|
||||||
}
|
|
||||||
catch (Exception e) {
|
|
||||||
throw new AssertionFailure( "Could not generate UUID");
|
|
||||||
}
|
|
||||||
|
|
||||||
final StrategySelector strategySelector = serviceRegistry.getService( StrategySelector.class );
|
final StrategySelector strategySelector = serviceRegistry.getService( StrategySelector.class );
|
||||||
ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class );
|
ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class );
|
||||||
|
|
|
@ -0,0 +1,23 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.id.uuid;
|
||||||
|
|
||||||
|
import org.hibernate.type.descriptor.java.UUIDTypeDescriptor;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class LocalObjectUuidHelper {
|
||||||
|
private LocalObjectUuidHelper() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public static String generateLocalObjectUuid() {
|
||||||
|
return UUIDTypeDescriptor.ToStringTransformer.INSTANCE.transform(
|
||||||
|
StandardRandomStrategy.INSTANCE.generateUUID( null )
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -180,7 +180,7 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( entityName == null ) {
|
if ( entityName == null ) {
|
||||||
for ( EntityNameResolver resolver : scope.resolveFactory().getMetamodel().getEntityNameResolvers() ) {
|
for ( EntityNameResolver resolver : scope.getTypeConfiguration().getSessionFactory().getMetamodel().getEntityNameResolvers() ) {
|
||||||
entityName = resolver.resolveEntityName( entity );
|
entityName = resolver.resolveEntityName( entity );
|
||||||
if ( entityName != null ) {
|
if ( entityName != null ) {
|
||||||
break;
|
break;
|
||||||
|
@ -193,7 +193,7 @@ public class AnyType extends AbstractType implements CompositeType, AssociationT
|
||||||
entityName = object.getClass().getName();
|
entityName = object.getClass().getName();
|
||||||
}
|
}
|
||||||
|
|
||||||
return scope.resolveFactory().getMetamodel().entityPersister( entityName );
|
return scope.getTypeConfiguration().getSessionFactory().getMetamodel().entityPersister( entityName );
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|
|
@ -46,6 +46,8 @@ import org.hibernate.persister.entity.Joinable;
|
||||||
import org.hibernate.pretty.MessageHelper;
|
import org.hibernate.pretty.MessageHelper;
|
||||||
import org.hibernate.proxy.HibernateProxy;
|
import org.hibernate.proxy.HibernateProxy;
|
||||||
import org.hibernate.proxy.LazyInitializer;
|
import org.hibernate.proxy.LazyInitializer;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
import org.jboss.logging.Logger;
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -16,6 +16,7 @@ import org.hibernate.collection.spi.PersistentCollection;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
import org.hibernate.engine.spi.SharedSessionContractImplementor;
|
||||||
import org.hibernate.persister.collection.CollectionPersister;
|
import org.hibernate.persister.collection.CollectionPersister;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.LoggableUserType;
|
import org.hibernate.usertype.LoggableUserType;
|
||||||
import org.hibernate.usertype.UserCollectionType;
|
import org.hibernate.usertype.UserCollectionType;
|
||||||
|
|
||||||
|
|
|
@ -252,7 +252,7 @@ public abstract class EntityType extends AbstractType implements AssociationType
|
||||||
return ReflectHelper.classForName( entityName );
|
return ReflectHelper.classForName( entityName );
|
||||||
}
|
}
|
||||||
catch (ClassNotFoundException cnfe) {
|
catch (ClassNotFoundException cnfe) {
|
||||||
return this.scope.resolveFactory().getMetamodel().entityPersister( entityName ).
|
return this.scope.getTypeConfiguration().resolveSessionFactory().getMetamodel().entityPersister( entityName ).
|
||||||
getEntityTuplizer().getMappedClass();
|
getEntityTuplizer().getMappedClass();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,37 +33,28 @@ import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||||
*
|
*
|
||||||
* @author Gavin King
|
* @author Gavin King
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
*
|
||||||
|
* @deprecated Use {@link TypeConfiguration} instead
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
@SuppressWarnings({"unchecked"})
|
@SuppressWarnings({"unchecked"})
|
||||||
public final class TypeFactory implements Serializable {
|
public final class TypeFactory implements Serializable {
|
||||||
private static final CoreMessageLogger LOG = messageLogger( TypeFactory.class );
|
private static final CoreMessageLogger LOG = messageLogger( TypeFactory.class );
|
||||||
|
|
||||||
private final TypeScopeImpl typeScope = new TypeScopeImpl();
|
/**
|
||||||
|
* @deprecated Use {@link TypeConfiguration}/{@link TypeConfiguration.Scope} instead
|
||||||
|
*/
|
||||||
|
@Deprecated
|
||||||
public interface TypeScope extends Serializable {
|
public interface TypeScope extends Serializable {
|
||||||
SessionFactoryImplementor resolveFactory();
|
TypeConfiguration getTypeConfiguration();
|
||||||
}
|
}
|
||||||
|
|
||||||
private final TypeConfiguration typeConfiguration;
|
private final TypeConfiguration typeConfiguration;
|
||||||
|
private final TypeScope typeScope;
|
||||||
|
|
||||||
public TypeFactory(TypeConfiguration typeConfiguration) {
|
public TypeFactory(TypeConfiguration typeConfiguration) {
|
||||||
this.typeConfiguration = typeConfiguration;
|
this.typeConfiguration = typeConfiguration;
|
||||||
}
|
this.typeScope = (TypeScope) () -> typeConfiguration;
|
||||||
|
|
||||||
private static class TypeScopeImpl implements TypeFactory.TypeScope {
|
|
||||||
private transient SessionFactoryImplementor factory;
|
|
||||||
|
|
||||||
public void injectSessionFactory(SessionFactoryImplementor factory) {
|
|
||||||
this.factory = factory;
|
|
||||||
}
|
|
||||||
|
|
||||||
public SessionFactoryImplementor resolveFactory() {
|
|
||||||
return factory;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void injectSessionFactory(SessionFactoryImplementor factory) {
|
|
||||||
typeScope.injectSessionFactory( factory );
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public SessionFactoryImplementor resolveSessionFactory() {
|
public SessionFactoryImplementor resolveSessionFactory() {
|
||||||
|
|
|
@ -18,7 +18,10 @@ import java.util.Map;
|
||||||
* Collection of convenience methods relating to operations across arrays of types...
|
* Collection of convenience methods relating to operations across arrays of types...
|
||||||
*
|
*
|
||||||
* @author Steve Ebersole
|
* @author Steve Ebersole
|
||||||
|
*
|
||||||
|
* @deprecated with no real replacement. this was always intended as an internal class
|
||||||
*/
|
*/
|
||||||
|
@Deprecated
|
||||||
public class TypeHelper {
|
public class TypeHelper {
|
||||||
/**
|
/**
|
||||||
* Disallow instantiation
|
* Disallow instantiation
|
||||||
|
|
|
@ -0,0 +1,60 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later
|
||||||
|
* See the lgpl.txt file in the root directory or http://www.gnu.org/licenses/lgpl-2.1.html
|
||||||
|
*/
|
||||||
|
package org.hibernate.type.internal;
|
||||||
|
|
||||||
|
import java.util.concurrent.ConcurrentHashMap;
|
||||||
|
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
|
|
||||||
|
import org.jboss.logging.Logger;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A Registry of TypeConfiguration references based on the
|
||||||
|
* TypeConfiguration's UUID.
|
||||||
|
*
|
||||||
|
* @author Steve Ebersole
|
||||||
|
*/
|
||||||
|
public class TypeConfigurationRegistry {
|
||||||
|
private static final Logger LOG = Logger.getLogger( TypeConfigurationRegistry.class );
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Singleton access
|
||||||
|
*/
|
||||||
|
public static final TypeConfigurationRegistry INSTANCE = new TypeConfigurationRegistry();
|
||||||
|
|
||||||
|
private TypeConfigurationRegistry() {
|
||||||
|
}
|
||||||
|
|
||||||
|
private ConcurrentHashMap<String,TypeConfiguration> configurationMap;
|
||||||
|
|
||||||
|
public void registerTypeConfiguration(TypeConfiguration typeConfiguration) {
|
||||||
|
if ( configurationMap == null ) {
|
||||||
|
configurationMap = new ConcurrentHashMap<>();
|
||||||
|
}
|
||||||
|
configurationMap.put( typeConfiguration.getUuid(), typeConfiguration );
|
||||||
|
}
|
||||||
|
|
||||||
|
public TypeConfiguration findTypeConfiguration(String uuid) {
|
||||||
|
if ( configurationMap == null ) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
return configurationMap.get( uuid );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void deregisterTypeConfiguration(TypeConfiguration typeConfiguration) {
|
||||||
|
final TypeConfiguration existing = configurationMap.remove( typeConfiguration.getUuid() );
|
||||||
|
if ( existing != typeConfiguration ) {
|
||||||
|
LOG.debugf(
|
||||||
|
"Different TypeConfiguration [%s] passed to #deregisterTypeConfiguration than previously registered [%s] under that UUID [%s]",
|
||||||
|
typeConfiguration,
|
||||||
|
existing,
|
||||||
|
typeConfiguration.getUuid()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -6,6 +6,7 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.type.spi;
|
package org.hibernate.type.spi;
|
||||||
|
|
||||||
|
import java.io.InvalidObjectException;
|
||||||
import java.io.Serializable;
|
import java.io.Serializable;
|
||||||
import java.util.Collections;
|
import java.util.Collections;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
@ -19,6 +20,7 @@ import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
|
||||||
import org.hibernate.boot.spi.BootstrapContext;
|
import org.hibernate.boot.spi.BootstrapContext;
|
||||||
import org.hibernate.boot.spi.MetadataBuildingContext;
|
import org.hibernate.boot.spi.MetadataBuildingContext;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
|
import org.hibernate.id.uuid.LocalObjectUuidHelper;
|
||||||
import org.hibernate.internal.CoreMessageLogger;
|
import org.hibernate.internal.CoreMessageLogger;
|
||||||
import org.hibernate.internal.SessionFactoryRegistry;
|
import org.hibernate.internal.SessionFactoryRegistry;
|
||||||
import org.hibernate.metamodel.internal.MetamodelImpl;
|
import org.hibernate.metamodel.internal.MetamodelImpl;
|
||||||
|
@ -29,6 +31,7 @@ import org.hibernate.type.TypeFactory;
|
||||||
import org.hibernate.type.TypeResolver;
|
import org.hibernate.type.TypeResolver;
|
||||||
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
import org.hibernate.type.descriptor.java.spi.JavaTypeDescriptorRegistry;
|
||||||
import org.hibernate.type.descriptor.sql.spi.SqlTypeDescriptorRegistry;
|
import org.hibernate.type.descriptor.sql.spi.SqlTypeDescriptorRegistry;
|
||||||
|
import org.hibernate.type.internal.TypeConfigurationRegistry;
|
||||||
|
|
||||||
import static org.hibernate.internal.CoreLogging.messageLogger;
|
import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||||
|
|
||||||
|
@ -54,28 +57,36 @@ import static org.hibernate.internal.CoreLogging.messageLogger;
|
||||||
public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
private static final CoreMessageLogger log = messageLogger( Scope.class );
|
private static final CoreMessageLogger log = messageLogger( Scope.class );
|
||||||
|
|
||||||
// todo : (
|
private final String uuid = LocalObjectUuidHelper.generateLocalObjectUuid();
|
||||||
|
|
||||||
private final Scope scope;
|
private final Scope scope;
|
||||||
private final TypeFactory typeFactory;
|
private final transient TypeFactory typeFactory;
|
||||||
|
|
||||||
// things available during both boot and runtime ("active") lifecycle phases
|
// things available during both boot and runtime ("active") lifecycle phases
|
||||||
private final JavaTypeDescriptorRegistry javaTypeDescriptorRegistry;
|
private final transient JavaTypeDescriptorRegistry javaTypeDescriptorRegistry;
|
||||||
private final SqlTypeDescriptorRegistry sqlTypeDescriptorRegistry;
|
private final transient SqlTypeDescriptorRegistry sqlTypeDescriptorRegistry;
|
||||||
private final BasicTypeRegistry basicTypeRegistry;
|
private final transient BasicTypeRegistry basicTypeRegistry;
|
||||||
|
|
||||||
private final Map<String,String> importMap = new ConcurrentHashMap<>();
|
private final transient Map<String,String> importMap = new ConcurrentHashMap<>();
|
||||||
|
|
||||||
|
|
||||||
// temporarily needed to support deprecations
|
// temporarily needed to support deprecations
|
||||||
private final TypeResolver typeResolver;
|
private final transient TypeResolver typeResolver;
|
||||||
|
|
||||||
public TypeConfiguration() {
|
public TypeConfiguration() {
|
||||||
this.scope = new Scope();
|
this.scope = new Scope();
|
||||||
this.javaTypeDescriptorRegistry = new JavaTypeDescriptorRegistry( this );
|
this.javaTypeDescriptorRegistry = new JavaTypeDescriptorRegistry( this );
|
||||||
this.sqlTypeDescriptorRegistry = new SqlTypeDescriptorRegistry( this );
|
this.sqlTypeDescriptorRegistry = new SqlTypeDescriptorRegistry( this );
|
||||||
basicTypeRegistry = new BasicTypeRegistry();
|
|
||||||
typeFactory = new TypeFactory( this );
|
this.basicTypeRegistry = new BasicTypeRegistry();
|
||||||
typeResolver = new TypeResolver( this, typeFactory );
|
this.typeFactory = new TypeFactory( this );
|
||||||
|
this.typeResolver = new TypeResolver( this, typeFactory );
|
||||||
|
|
||||||
|
TypeConfigurationRegistry.INSTANCE.registerTypeConfiguration( this );
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getUuid() {
|
||||||
|
return uuid;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -134,7 +145,6 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
public MetamodelImplementor scope(SessionFactoryImplementor sessionFactory, BootstrapContext bootstrapContext) {
|
public MetamodelImplementor scope(SessionFactoryImplementor sessionFactory, BootstrapContext bootstrapContext) {
|
||||||
log.debugf( "Scoping TypeConfiguration [%s] to SessionFactoryImpl [%s]", this, sessionFactory );
|
log.debugf( "Scoping TypeConfiguration [%s] to SessionFactoryImpl [%s]", this, sessionFactory );
|
||||||
scope.setSessionFactory( sessionFactory );
|
scope.setSessionFactory( sessionFactory );
|
||||||
typeFactory.injectSessionFactory( sessionFactory );
|
|
||||||
log.debugf( "Scoping TypeConfiguration [%s] to SessionFactory [%s]", this, sessionFactory );
|
log.debugf( "Scoping TypeConfiguration [%s] to SessionFactory [%s]", this, sessionFactory );
|
||||||
|
|
||||||
for ( Map.Entry<String, String> importEntry : scope.metadataBuildingContext.getMetadataCollector().getImports().entrySet() ) {
|
for ( Map.Entry<String, String> importEntry : scope.metadataBuildingContext.getMetadataCollector().getImports().entrySet() ) {
|
||||||
|
@ -178,6 +188,9 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
@Override
|
@Override
|
||||||
public void sessionFactoryClosed(SessionFactory factory) {
|
public void sessionFactoryClosed(SessionFactory factory) {
|
||||||
log.tracef( "Handling #sessionFactoryClosed from [%s] for TypeConfiguration", factory );
|
log.tracef( "Handling #sessionFactoryClosed from [%s] for TypeConfiguration", factory );
|
||||||
|
|
||||||
|
TypeConfigurationRegistry.INSTANCE.deregisterTypeConfiguration( this );
|
||||||
|
|
||||||
scope.unsetSessionFactory( factory );
|
scope.unsetSessionFactory( factory );
|
||||||
|
|
||||||
// todo (6.0) : finish this
|
// todo (6.0) : finish this
|
||||||
|
@ -185,6 +198,10 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
// valid while the TypeConfiguration is scoped to SessionFactory
|
// valid while the TypeConfiguration is scoped to SessionFactory
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public SessionFactoryImplementor resolveSessionFactory() {
|
||||||
|
return scope.resolveSessionFactory();
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Encapsulation of lifecycle concerns for a TypeConfiguration, mainly in
|
* Encapsulation of lifecycle concerns for a TypeConfiguration, mainly in
|
||||||
* regards to eventually being associated with a SessionFactory. Goes
|
* regards to eventually being associated with a SessionFactory. Goes
|
||||||
|
@ -278,5 +295,55 @@ public class TypeConfiguration implements SessionFactoryObserver, Serializable {
|
||||||
log.debugf( "Un-scoping TypeConfiguration [%s] from SessionFactory [%s]", this, factory );
|
log.debugf( "Un-scoping TypeConfiguration [%s] from SessionFactory [%s]", this, factory );
|
||||||
this.sessionFactory = null;
|
this.sessionFactory = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Custom serialization hook
|
||||||
|
|
||||||
|
private Object readResolve() throws InvalidObjectException {
|
||||||
|
if ( sessionFactory == null ) {
|
||||||
|
if ( sessionFactoryName != null || sessionFactoryUuid != null ) {
|
||||||
|
sessionFactory = (SessionFactoryImplementor) SessionFactoryRegistry.INSTANCE.findSessionFactory(
|
||||||
|
sessionFactoryUuid,
|
||||||
|
sessionFactoryName
|
||||||
|
);
|
||||||
|
|
||||||
|
if ( sessionFactory == null ) {
|
||||||
|
throw new HibernateException(
|
||||||
|
"Could not find a SessionFactory [uuid=" + sessionFactoryUuid + ",name=" + sessionFactoryName + "]"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SessionFactoryImplementor resolveSessionFactory() {
|
||||||
|
// if ( sessionFactory == null ) {
|
||||||
|
// if ( sessionFactoryName != null || sessionFactoryUuid != null ) {
|
||||||
|
// sessionFactory = (SessionFactoryImplementor) SessionFactoryRegistry.INSTANCE.findSessionFactory(
|
||||||
|
// sessionFactoryUuid,
|
||||||
|
// sessionFactoryName
|
||||||
|
// );
|
||||||
|
//
|
||||||
|
// if ( sessionFactory == null ) {
|
||||||
|
// throw new HibernateException(
|
||||||
|
// "Could not find a SessionFactory [uuid=" + sessionFactoryUuid + ",name=" + sessionFactoryName + "]"
|
||||||
|
// );
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
// }
|
||||||
|
return sessionFactory;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
// Custom serialization hook
|
||||||
|
|
||||||
|
private Object readResolve() throws InvalidObjectException {
|
||||||
|
log.trace( "Resolving serialized TypeConfiguration - readResolve" );
|
||||||
|
return TypeConfigurationRegistry.INSTANCE.findTypeConfiguration( getUuid() );
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.hibernate.type.StandardBasicTypes;
|
||||||
import org.hibernate.type.StringType;
|
import org.hibernate.type.StringType;
|
||||||
import org.hibernate.type.Type;
|
import org.hibernate.type.Type;
|
||||||
import org.hibernate.type.TypeFactory;
|
import org.hibernate.type.TypeFactory;
|
||||||
|
import org.hibernate.type.spi.TypeConfiguration;
|
||||||
import org.hibernate.usertype.CompositeUserType;
|
import org.hibernate.usertype.CompositeUserType;
|
||||||
|
|
||||||
public class MultiplicityType implements CompositeUserType {
|
public class MultiplicityType implements CompositeUserType {
|
||||||
|
@ -40,8 +41,7 @@ public class MultiplicityType implements CompositeUserType {
|
||||||
new ManyToOneType(
|
new ManyToOneType(
|
||||||
new TypeFactory.TypeScope() {
|
new TypeFactory.TypeScope() {
|
||||||
@Override
|
@Override
|
||||||
public SessionFactoryImplementor resolveFactory() {
|
public TypeConfiguration getTypeConfiguration() {
|
||||||
// todo : can we tie this into org.hibernate.type.TypeFactory.TypeScopeImpl() somehow?
|
|
||||||
throw new HibernateException( "Cannot access SessionFactory from here" );
|
throw new HibernateException( "Cannot access SessionFactory from here" );
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
|
@ -6,19 +6,17 @@
|
||||||
*/
|
*/
|
||||||
package org.hibernate.test.serialization;
|
package org.hibernate.test.serialization;
|
||||||
|
|
||||||
import org.junit.Test;
|
|
||||||
|
|
||||||
import org.hibernate.HibernateException;
|
import org.hibernate.HibernateException;
|
||||||
import org.hibernate.cfg.AvailableSettings;
|
import org.hibernate.cfg.AvailableSettings;
|
||||||
import org.hibernate.cfg.Configuration;
|
import org.hibernate.cfg.Configuration;
|
||||||
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
import org.hibernate.engine.spi.SessionFactoryImplementor;
|
||||||
import org.hibernate.internal.SessionFactoryRegistry;
|
import org.hibernate.internal.SessionFactoryRegistry;
|
||||||
import org.hibernate.internal.util.SerializationHelper;
|
import org.hibernate.internal.util.SerializationHelper;
|
||||||
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
|
||||||
import org.hibernate.type.TypeFactory;
|
import org.hibernate.type.TypeFactory;
|
||||||
|
|
||||||
import static org.junit.Assert.assertFalse;
|
import org.hibernate.testing.junit4.BaseUnitTestCase;
|
||||||
import static org.junit.Assert.assertNull;
|
import org.junit.Test;
|
||||||
|
|
||||||
import static org.junit.Assert.assertSame;
|
import static org.junit.Assert.assertSame;
|
||||||
import static org.junit.Assert.fail;
|
import static org.junit.Assert.fail;
|
||||||
|
|
||||||
|
@ -29,161 +27,35 @@ public class TypeFactorySerializationTest extends BaseUnitTestCase {
|
||||||
private static String NAME = "test name";
|
private static String NAME = "test name";
|
||||||
|
|
||||||
@Test
|
@Test
|
||||||
public void testWithSameRegisteredSessionFactory() throws Exception {
|
public void testTypeFactoryDeserializedAfterSessionFactoryClosed() {
|
||||||
Configuration cfg = new Configuration()
|
Configuration cfg = new Configuration()
|
||||||
.setProperty( AvailableSettings.SESSION_FACTORY_NAME, NAME )
|
.setProperty( AvailableSettings.SESSION_FACTORY_NAME, NAME )
|
||||||
.setProperty( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, "false" ); // default is true
|
.setProperty( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, "false" ); // default is true
|
||||||
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
||||||
|
|
||||||
// Session factory is registered.
|
|
||||||
assertSame( factory, SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( NAME ) );
|
|
||||||
|
|
||||||
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
|
|
||||||
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
|
|
||||||
typeFactory = (TypeFactory) SerializationHelper.deserialize( typeFactoryBytes );
|
|
||||||
|
|
||||||
assertSame( factory, typeFactory.resolveSessionFactory() );
|
|
||||||
factory.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnregisterSerializeRegisterSameSessionFactory() throws Exception {
|
|
||||||
Configuration cfg = new Configuration()
|
|
||||||
.setProperty( AvailableSettings.SESSION_FACTORY_NAME, NAME )
|
|
||||||
.setProperty( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, "false" ); // default is true
|
|
||||||
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
|
||||||
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 ) );
|
|
||||||
|
|
||||||
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
|
|
||||||
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
|
|
||||||
typeFactory = (TypeFactory) SerializationHelper.deserialize( typeFactoryBytes );
|
|
||||||
|
|
||||||
try {
|
try {
|
||||||
typeFactory.resolveSessionFactory();
|
// SessionFactory is registered.
|
||||||
fail( "should have failed with HibernateException because session factory is not registered." );
|
assertSame( factory, SessionFactoryRegistry.INSTANCE.getNamedSessionFactory( NAME ) );
|
||||||
|
|
||||||
|
// get reference to the TypeFactory and serialize it
|
||||||
|
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
|
||||||
|
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
|
||||||
|
|
||||||
|
// close the SessionFactory
|
||||||
|
factory.close();
|
||||||
|
|
||||||
|
// now try to deserialize the TypeFactory.. it should fail
|
||||||
|
try {
|
||||||
|
typeFactory = (TypeFactory) SerializationHelper.deserialize( typeFactoryBytes );
|
||||||
|
fail();
|
||||||
|
}
|
||||||
|
catch (HibernateException expected) {
|
||||||
|
}
|
||||||
}
|
}
|
||||||
catch ( HibernateException ex ) {
|
finally {
|
||||||
// expected because the session factory is not registered.
|
if ( factory != null && factory.isOpen() ) {
|
||||||
|
factory.close();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Re-register the same session factory.
|
|
||||||
SessionFactoryRegistry.INSTANCE.addSessionFactory( factory.getUuid(), NAME, false, factory, null );
|
|
||||||
|
|
||||||
// Session factory resolved from typeFactory should be the new session factory
|
|
||||||
// (because it is resolved from SessionFactoryRegistry.INSTANCE)
|
|
||||||
assertSame( factory, typeFactory.resolveSessionFactory() );
|
|
||||||
factory.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnregisterSerializeRegisterSameSessionFactoryNoName() throws Exception {
|
|
||||||
Configuration cfg = new Configuration();
|
|
||||||
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
|
||||||
assertSame( factory, SessionFactoryRegistry.INSTANCE.findSessionFactory( factory.getUuid(), null ) );
|
|
||||||
|
|
||||||
// Remove the session factory from the registry
|
|
||||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( factory.getUuid(), null, false, null );
|
|
||||||
assertNull( SessionFactoryRegistry.INSTANCE.findSessionFactory( factory.getUuid(), null ) );
|
|
||||||
|
|
||||||
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
|
|
||||||
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
|
|
||||||
typeFactory = (TypeFactory) SerializationHelper.deserialize( typeFactoryBytes );
|
|
||||||
|
|
||||||
try {
|
|
||||||
typeFactory.resolveSessionFactory();
|
|
||||||
fail( "should have failed with HibernateException because session factory is not registered." );
|
|
||||||
}
|
|
||||||
catch ( HibernateException ex ) {
|
|
||||||
// expected because the session factory is not registered.
|
|
||||||
}
|
|
||||||
|
|
||||||
// Re-register the same session factory.
|
|
||||||
SessionFactoryRegistry.INSTANCE.addSessionFactory( factory.getUuid(), null, false, factory, null );
|
|
||||||
|
|
||||||
// Session factory resolved from typeFactory should be the new session factory
|
|
||||||
// (because it is resolved from SessionFactoryRegistry.INSTANCE)
|
|
||||||
assertSame( factory, typeFactory.resolveSessionFactory() );
|
|
||||||
factory.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnregisterSerializeRegisterDiffSessionFactory() throws Exception {
|
|
||||||
Configuration cfg = new Configuration()
|
|
||||||
.setProperty( AvailableSettings.SESSION_FACTORY_NAME, NAME )
|
|
||||||
.setProperty( AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, "false" ); // default is true
|
|
||||||
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
|
||||||
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 ) );
|
|
||||||
|
|
||||||
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
|
|
||||||
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
|
|
||||||
typeFactory = (TypeFactory) SerializationHelper.deserialize( typeFactoryBytes );
|
|
||||||
|
|
||||||
try {
|
|
||||||
typeFactory.resolveSessionFactory();
|
|
||||||
fail( "should have failed with HibernateException because session factory is not registered." );
|
|
||||||
}
|
|
||||||
catch ( HibernateException ex ) {
|
|
||||||
// expected because the session factory is not registered.
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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() ) );
|
|
||||||
|
|
||||||
// Session factory resolved from typeFactory should be the new session factory
|
|
||||||
// (because it is resolved from SessionFactoryRegistry.INSTANCE)
|
|
||||||
assertSame( factoryWithSameName, typeFactory.resolveSessionFactory() );
|
|
||||||
|
|
||||||
factory.close();
|
|
||||||
factoryWithSameName.close();
|
|
||||||
}
|
|
||||||
|
|
||||||
@Test
|
|
||||||
public void testUnregisterSerializeRegisterDiffSessionFactoryNoName() throws Exception {
|
|
||||||
Configuration cfg = new Configuration();
|
|
||||||
SessionFactoryImplementor factory = (SessionFactoryImplementor) cfg.buildSessionFactory();
|
|
||||||
assertSame( factory, SessionFactoryRegistry.INSTANCE.getSessionFactory( factory.getUuid() ) );
|
|
||||||
|
|
||||||
// Remove the session factory from the registry
|
|
||||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( factory.getUuid(), null, false, null );
|
|
||||||
assertNull( SessionFactoryRegistry.INSTANCE.getSessionFactory( factory.getUuid() ) );
|
|
||||||
|
|
||||||
TypeFactory typeFactory = factory.getTypeResolver().getTypeFactory();
|
|
||||||
byte[] typeFactoryBytes = SerializationHelper.serialize( typeFactory );
|
|
||||||
typeFactory = (TypeFactory) SerializationHelper.deserialize( typeFactoryBytes );
|
|
||||||
|
|
||||||
try {
|
|
||||||
typeFactory.resolveSessionFactory();
|
|
||||||
fail( "should have failed with HibernateException because session factory is not registered." );
|
|
||||||
}
|
|
||||||
catch ( HibernateException ex ) {
|
|
||||||
// expected because the session factory is not registered.
|
|
||||||
}
|
|
||||||
|
|
||||||
// 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() ) );
|
|
||||||
|
|
||||||
// It should not be possible to resolve the session factory with no name configured.
|
|
||||||
try {
|
|
||||||
typeFactory.resolveSessionFactory();
|
|
||||||
fail( "should have failed with HibernateException because session factories were not registered with the same non-null name." );
|
|
||||||
}
|
|
||||||
catch ( HibernateException ex ) {
|
|
||||||
// expected
|
|
||||||
}
|
|
||||||
|
|
||||||
factory.close();
|
|
||||||
factoryWithDiffUuid.close();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue