HHH-18048 - Split notions of SessionFactory name and SessionFactory JNDI name
This commit is contained in:
parent
d91bcecf77
commit
2284b2b142
|
@ -137,6 +137,11 @@ import static org.hibernate.internal.TransactionManagement.manageTransaction;
|
|||
* @author Steve Ebersole
|
||||
*/
|
||||
public interface SessionFactory extends EntityManagerFactory, Referenceable, Serializable, java.io.Closeable {
|
||||
/**
|
||||
* The JNDI name, used to bind the SessionFactory to JNDI
|
||||
*/
|
||||
String getJndiName();
|
||||
|
||||
/**
|
||||
* Obtain a {@linkplain SessionBuilder session builder} for creating
|
||||
* new {@link Session}s with certain customized options.
|
||||
|
|
|
@ -84,7 +84,9 @@ public interface SessionFactoryBuilder {
|
|||
*
|
||||
* @return {@code this}, for method chaining
|
||||
*
|
||||
* @see org.hibernate.cfg.AvailableSettings#SESSION_FACTORY_NAME
|
||||
* @see org.hibernate.cfg.AvailableSettings#SESSION_FACTORY_NAME_IS_JNDI
|
||||
* @see org.hibernate.cfg.AvailableSettings#SESSION_FACTORY_JNDI_NAME
|
||||
*/
|
||||
SessionFactoryBuilder applyNameAsJndiName(boolean isJndiName);
|
||||
|
||||
|
|
|
@ -23,19 +23,16 @@ import org.hibernate.internal.SessionFactoryRegistry;
|
|||
* @author Gavin King
|
||||
*/
|
||||
class SessionFactoryObserverForRegistration implements SessionFactoryObserver {
|
||||
|
||||
private JndiService jndiService;
|
||||
private boolean registeredInJndi;
|
||||
|
||||
@Override
|
||||
public void sessionFactoryCreated(SessionFactory factory) {
|
||||
final SessionFactoryImplementor sessionFactory = (SessionFactoryImplementor) factory;
|
||||
jndiService = sessionFactory.getServiceRegistry().getService( JndiService.class );
|
||||
registeredInJndi = sessionFactory.getSessionFactoryOptions().isSessionFactoryNameAlsoJndiName();
|
||||
SessionFactoryRegistry.INSTANCE.addSessionFactory(
|
||||
sessionFactory.getUuid(),
|
||||
sessionFactory.getName(),
|
||||
registeredInJndi,
|
||||
sessionFactory.getJndiName(),
|
||||
sessionFactory,
|
||||
jndiService
|
||||
);
|
||||
|
@ -47,7 +44,7 @@ class SessionFactoryObserverForRegistration implements SessionFactoryObserver {
|
|||
SessionFactoryRegistry.INSTANCE.removeSessionFactory(
|
||||
sessionFactory.getUuid(),
|
||||
sessionFactory.getName(),
|
||||
registeredInJndi,
|
||||
sessionFactory.getJndiName(),
|
||||
jndiService
|
||||
);
|
||||
}
|
||||
|
|
|
@ -171,7 +171,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
// SessionFactory behavior
|
||||
private final boolean jpaBootstrap;
|
||||
private String sessionFactoryName;
|
||||
private boolean sessionFactoryNameAlsoJndiName;
|
||||
private Boolean sessionFactoryNameAlsoJndiName;
|
||||
|
||||
// Session behavior
|
||||
private boolean flushBeforeCompletionEnabled;
|
||||
|
@ -931,7 +931,7 @@ public class SessionFactoryOptionsBuilder implements SessionFactoryOptions {
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isSessionFactoryNameAlsoJndiName() {
|
||||
public Boolean isSessionFactoryNameAlsoJndiName() {
|
||||
return sessionFactoryNameAlsoJndiName;
|
||||
}
|
||||
|
||||
|
|
|
@ -101,7 +101,7 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
|
|||
}
|
||||
|
||||
@Override
|
||||
public boolean isSessionFactoryNameAlsoJndiName() {
|
||||
public Boolean isSessionFactoryNameAlsoJndiName() {
|
||||
return delegate.isSessionFactoryNameAlsoJndiName();
|
||||
}
|
||||
|
||||
|
|
|
@ -85,10 +85,10 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
|
|||
}
|
||||
|
||||
/**
|
||||
* The name to be used for the SessionFactory. This is used both in:<ul>
|
||||
* <li>in-VM serialization</li>
|
||||
* <li>JNDI binding, depending on {@link #isSessionFactoryNameAlsoJndiName}</li>
|
||||
* </ul>
|
||||
* The name to be used for the SessionFactory. This is used during in-VM serialization; see
|
||||
* {@link org.hibernate.internal.SessionFactoryRegistry}.
|
||||
* May also be used as a JNDI name depending on {@value org.hibernate.cfg.PersistenceSettings#SESSION_FACTORY_JNDI_NAME}
|
||||
* and {@value org.hibernate.cfg.PersistenceSettings#SESSION_FACTORY_NAME_IS_JNDI}.
|
||||
*
|
||||
* @return The SessionFactory name
|
||||
*/
|
||||
|
@ -100,7 +100,7 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
|
|||
*
|
||||
* @return {@code true} if the SessionFactory name is also a JNDI name; {@code false} otherwise.
|
||||
*/
|
||||
boolean isSessionFactoryNameAlsoJndiName();
|
||||
Boolean isSessionFactoryNameAlsoJndiName();
|
||||
|
||||
boolean isFlushBeforeCompletionEnabled();
|
||||
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
package org.hibernate.cfg;
|
||||
|
||||
import org.hibernate.Incubating;
|
||||
import org.hibernate.SessionFactory;
|
||||
import org.hibernate.SessionFactoryObserver;
|
||||
|
||||
import jakarta.persistence.spi.PersistenceUnitInfo;
|
||||
|
@ -61,15 +62,26 @@ public interface PersistenceSettings {
|
|||
* Naming the SessionFactory allows for it to be properly serialized across JVMs as
|
||||
* long as the same name is used on each JVM.
|
||||
* <p>
|
||||
* If {@link #SESSION_FACTORY_NAME_IS_JNDI} is set to {@code true}, this is also the
|
||||
* name under which the SessionFactory is bound into JNDI on startup and from which
|
||||
* it can be obtained from JNDI.
|
||||
* If {@link #SESSION_FACTORY_NAME_IS_JNDI} is set to {@code true}, this name will
|
||||
* also be used as {@link #SESSION_FACTORY_JNDI_NAME}.
|
||||
*
|
||||
* @see #SESSION_FACTORY_JNDI_NAME
|
||||
* @see org.hibernate.internal.SessionFactoryRegistry
|
||||
* @see org.hibernate.boot.SessionFactoryBuilder#applyName(String)
|
||||
*/
|
||||
String SESSION_FACTORY_NAME = "hibernate.session_factory_name";
|
||||
|
||||
/**
|
||||
* An optional name used to bind the SessionFactory into JNDI.
|
||||
* <p>
|
||||
* If {@link #SESSION_FACTORY_NAME_IS_JNDI} is set to {@code true},
|
||||
* {@link #SESSION_FACTORY_NAME} will be used as the JNDI name
|
||||
*
|
||||
* @see #SESSION_FACTORY_NAME_IS_JNDI
|
||||
* @see org.hibernate.internal.SessionFactoryRegistry
|
||||
* @see org.hibernate.boot.SessionFactoryBuilder#applyName(String)
|
||||
*/
|
||||
String SESSION_FACTORY_NAME = "hibernate.session_factory_name";
|
||||
String SESSION_FACTORY_JNDI_NAME = "hibernate.session_factory_jndi_name";
|
||||
|
||||
/**
|
||||
* Does the value defined by {@link #SESSION_FACTORY_NAME} represent a JNDI namespace
|
||||
|
@ -83,6 +95,10 @@ public interface PersistenceSettings {
|
|||
*
|
||||
* @see #SESSION_FACTORY_NAME
|
||||
* @see org.hibernate.boot.SessionFactoryBuilder#applyNameAsJndiName(boolean)
|
||||
*
|
||||
* @settingDefault {@code true} if {@link SessionFactory#getName()} comes from
|
||||
* {@value #SESSION_FACTORY_NAME}; {@code false} if there is no {@link SessionFactory#getName()}
|
||||
* or if it comes from {@value #PERSISTENCE_UNIT_NAME}
|
||||
*/
|
||||
String SESSION_FACTORY_NAME_IS_JNDI = "hibernate.session_factory_name_is_jndi";
|
||||
|
||||
|
|
|
@ -340,6 +340,11 @@ public class SessionFactoryDelegatingImpl implements SessionFactoryImplementor,
|
|||
return delegate.getName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJndiName() {
|
||||
return delegate.getJndiName();
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return delegate.getTypeConfiguration();
|
||||
|
|
|
@ -60,7 +60,6 @@ import org.hibernate.context.spi.CurrentSessionContext;
|
|||
import org.hibernate.context.spi.CurrentTenantIdentifierResolver;
|
||||
import org.hibernate.dialect.Dialect;
|
||||
import org.hibernate.engine.config.spi.ConfigurationService;
|
||||
import org.hibernate.engine.config.spi.StandardConverters;
|
||||
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
|
||||
import org.hibernate.engine.jdbc.spi.JdbcServices;
|
||||
import org.hibernate.engine.profile.FetchProfile;
|
||||
|
@ -144,6 +143,8 @@ import static org.hibernate.cfg.AvailableSettings.CREATE_EMPTY_COMPOSITES_ENABLE
|
|||
import static org.hibernate.cfg.AvailableSettings.CURRENT_SESSION_CONTEXT_CLASS;
|
||||
import static org.hibernate.cfg.AvailableSettings.JAKARTA_VALIDATION_FACTORY;
|
||||
import static org.hibernate.cfg.AvailableSettings.JPA_VALIDATION_FACTORY;
|
||||
import static org.hibernate.cfg.PersistenceSettings.PERSISTENCE_UNIT_NAME;
|
||||
import static org.hibernate.cfg.PersistenceSettings.SESSION_FACTORY_JNDI_NAME;
|
||||
import static org.hibernate.engine.config.spi.StandardConverters.STRING;
|
||||
import static org.hibernate.internal.FetchProfileHelper.getFetchProfiles;
|
||||
import static org.hibernate.internal.log.DeprecationLogger.DEPRECATION_LOGGER;
|
||||
|
@ -176,6 +177,7 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
private static final CoreMessageLogger LOG = CoreLogging.messageLogger( SessionFactoryImpl.class );
|
||||
|
||||
private final String name;
|
||||
private final String jndiName;
|
||||
private final String uuid;
|
||||
|
||||
private transient volatile Status status = Status.OPEN;
|
||||
|
@ -238,6 +240,7 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
bootMetamodel.initSessionFactory( this );
|
||||
|
||||
name = getSessionFactoryName( options, serviceRegistry );
|
||||
jndiName = determineJndiName( name, options, serviceRegistry );
|
||||
uuid = options.getUuid();
|
||||
|
||||
jdbcServices = serviceRegistry.requireService( JdbcServices.class );
|
||||
|
@ -346,7 +349,7 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
LOG.debug( "Instantiated SessionFactory" );
|
||||
}
|
||||
|
||||
private void deprecationCheck(Map<String, Object> settings) {
|
||||
private static void deprecationCheck(Map<String, Object> settings) {
|
||||
for ( String s:settings.keySet() ) {
|
||||
switch (s) {
|
||||
case "hibernate.hql.bulk_id_strategy.global_temporary.create_tables":
|
||||
|
@ -575,6 +578,23 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
return null;
|
||||
}
|
||||
|
||||
private String determineJndiName(
|
||||
String name,
|
||||
SessionFactoryOptions options,
|
||||
SessionFactoryServiceRegistry serviceRegistry) {
|
||||
final ConfigurationService cfgService = serviceRegistry.getService( ConfigurationService.class );
|
||||
assert cfgService != null;
|
||||
final String explicitJndiName = cfgService.getSetting( SESSION_FACTORY_JNDI_NAME, STRING );
|
||||
if ( StringHelper.isNotEmpty( explicitJndiName ) ) {
|
||||
return explicitJndiName;
|
||||
}
|
||||
|
||||
final String puName = cfgService.getSetting( PERSISTENCE_UNIT_NAME, STRING );
|
||||
// do not use name for JNDI if explicitly asked not to or if name comes from JPA persistence-unit name
|
||||
final boolean nameIsNotJndiName = options.isSessionFactoryNameAlsoJndiName() == Boolean.FALSE || StringHelper.isNotEmpty( puName );
|
||||
return !nameIsNotJndiName ? name : null;
|
||||
}
|
||||
|
||||
private SessionBuilderImpl createDefaultSessionOpenOptionsIfPossible() {
|
||||
final CurrentTenantIdentifierResolver<Object> currentTenantIdentifierResolver = getCurrentTenantIdentifierResolver();
|
||||
if ( currentTenantIdentifierResolver == null ) {
|
||||
|
@ -725,6 +745,11 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getJndiName() {
|
||||
return jndiName;
|
||||
}
|
||||
|
||||
@Override
|
||||
public TypeConfiguration getTypeConfiguration() {
|
||||
return runtimeMetamodels.getMappingMetamodel().getTypeConfiguration();
|
||||
|
@ -1766,7 +1791,7 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
return (SessionFactoryImpl) locateSessionFactoryOnDeserialization( uuid, name );
|
||||
}
|
||||
|
||||
private void maskOutSensitiveInformation(Map<String, Object> props) {
|
||||
private static void maskOutSensitiveInformation(Map<String, Object> props) {
|
||||
maskOutIfSet( props, AvailableSettings.JPA_JDBC_USER );
|
||||
maskOutIfSet( props, AvailableSettings.JPA_JDBC_PASSWORD );
|
||||
maskOutIfSet( props, AvailableSettings.JAKARTA_JDBC_USER );
|
||||
|
@ -1775,13 +1800,13 @@ public class SessionFactoryImpl extends QueryParameterBindingTypeResolverImpl im
|
|||
maskOutIfSet( props, AvailableSettings.PASS );
|
||||
}
|
||||
|
||||
private void maskOutIfSet(Map<String, Object> props, String setting) {
|
||||
private static void maskOutIfSet(Map<String, Object> props, String setting) {
|
||||
if ( props.containsKey( setting ) ) {
|
||||
props.put( setting, "****" );
|
||||
}
|
||||
}
|
||||
|
||||
private void logIfEmptyCompositesEnabled(Map<String, Object> props ) {
|
||||
private static void logIfEmptyCompositesEnabled(Map<String, Object> props ) {
|
||||
final boolean isEmptyCompositesEnabled = getBoolean( CREATE_EMPTY_COMPOSITES_ENABLED, props );
|
||||
if ( isEmptyCompositesEnabled ) {
|
||||
LOG.emptyCompositesEnabled();
|
||||
|
|
|
@ -57,14 +57,14 @@ public class SessionFactoryRegistry {
|
|||
*
|
||||
* @param uuid The uuid under which to register the SessionFactory
|
||||
* @param name The optional name under which to register the SessionFactory
|
||||
* @param isNameAlsoJndiName Is name, if provided, also a JNDI name?
|
||||
* @param jndiName An optional name to use for binding the SessionFactory into JNDI
|
||||
* @param instance The SessionFactory instance
|
||||
* @param jndiService The JNDI service, so we can register a listener if name is a JNDI name
|
||||
*/
|
||||
public void addSessionFactory(
|
||||
String uuid,
|
||||
String name,
|
||||
boolean isNameAlsoJndiName,
|
||||
String jndiName,
|
||||
SessionFactoryImplementor instance,
|
||||
JndiService jndiService) {
|
||||
if ( uuid == null ) {
|
||||
|
@ -77,25 +77,28 @@ public class SessionFactoryRegistry {
|
|||
nameUuidXref.put( name, uuid );
|
||||
}
|
||||
|
||||
if ( name == null || !isNameAlsoJndiName ) {
|
||||
if ( jndiName == null ) {
|
||||
LOG.debug( "Not binding SessionFactory to JNDI, no JNDI name configured" );
|
||||
return;
|
||||
}
|
||||
|
||||
LOG.debugf( "Attempting to bind SessionFactory [%s] to JNDI", name );
|
||||
bindToJndi( jndiName, instance, jndiService );
|
||||
}
|
||||
|
||||
private void bindToJndi(String jndiName, SessionFactoryImplementor instance, JndiService jndiService) {
|
||||
try {
|
||||
jndiService.bind( name, instance );
|
||||
LOG.factoryBoundToJndiName( name );
|
||||
LOG.debugf( "Attempting to bind SessionFactory [%s] to JNDI", jndiName );
|
||||
jndiService.bind( jndiName, instance );
|
||||
LOG.factoryBoundToJndiName( jndiName );
|
||||
try {
|
||||
jndiService.addListener( name, listener );
|
||||
jndiService.addListener( jndiName, listener );
|
||||
}
|
||||
catch (Exception e) {
|
||||
LOG.couldNotBindJndiListener();
|
||||
}
|
||||
}
|
||||
catch (JndiNameException e) {
|
||||
LOG.invalidJndiName( name, e );
|
||||
LOG.invalidJndiName( jndiName, e );
|
||||
}
|
||||
catch (JndiException e) {
|
||||
LOG.unableToBindFactoryToJndi( e );
|
||||
|
@ -107,29 +110,29 @@ public class SessionFactoryRegistry {
|
|||
*
|
||||
* @param uuid The uuid
|
||||
* @param name The optional name
|
||||
* @param isNameAlsoJndiName Is name, if provided, also a JNDI name?
|
||||
* @param jndiName An optional name to use for binding the SessionFactory nto JNDI
|
||||
* @param jndiService The JNDI service
|
||||
*/
|
||||
public void removeSessionFactory(
|
||||
String uuid,
|
||||
String name,
|
||||
boolean isNameAlsoJndiName,
|
||||
String jndiName,
|
||||
JndiService jndiService) {
|
||||
if ( name != null ) {
|
||||
nameUuidXref.remove( name );
|
||||
}
|
||||
|
||||
if ( isNameAlsoJndiName ) {
|
||||
try {
|
||||
LOG.tracef( "Unbinding SessionFactory from JNDI : %s", name );
|
||||
jndiService.unbind( name );
|
||||
LOG.factoryUnboundFromJndiName( name );
|
||||
}
|
||||
catch (JndiNameException e) {
|
||||
LOG.invalidJndiName( name, e );
|
||||
}
|
||||
catch (JndiException e) {
|
||||
LOG.unableToUnbindFactoryFromJndi( e );
|
||||
}
|
||||
if ( jndiName != null ) {
|
||||
try {
|
||||
LOG.tracef( "Unbinding SessionFactory from JNDI : %s", jndiName );
|
||||
jndiService.unbind( jndiName );
|
||||
LOG.factoryUnboundFromJndiName( jndiName );
|
||||
}
|
||||
catch (JndiNameException e) {
|
||||
LOG.invalidJndiName( jndiName, e );
|
||||
}
|
||||
catch (JndiException e) {
|
||||
LOG.unableToUnbindFactoryFromJndi( e );
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,95 @@
|
|||
/*
|
||||
* 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.orm.test.boot;
|
||||
|
||||
import org.hibernate.boot.model.process.internal.ScanningCoordinator;
|
||||
import org.hibernate.cfg.AvailableSettings;
|
||||
import org.hibernate.cfg.PersistenceSettings;
|
||||
import org.hibernate.internal.SessionFactoryRegistry;
|
||||
|
||||
import org.hibernate.testing.orm.junit.DomainModel;
|
||||
import org.hibernate.testing.orm.junit.Logger;
|
||||
import org.hibernate.testing.orm.junit.LoggingInspections;
|
||||
import org.hibernate.testing.orm.junit.MessageKeyInspection;
|
||||
import org.hibernate.testing.orm.junit.MessageKeyWatcher;
|
||||
import org.hibernate.testing.orm.junit.ServiceRegistry;
|
||||
import org.hibernate.testing.orm.junit.SessionFactory;
|
||||
import org.hibernate.testing.orm.junit.SessionFactoryScope;
|
||||
import org.hibernate.testing.orm.junit.Setting;
|
||||
import org.junit.jupiter.api.Test;
|
||||
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
|
||||
/**
|
||||
* @author Steve Ebersole
|
||||
*/
|
||||
@SuppressWarnings("JUnitMalformedDeclaration")
|
||||
@MessageKeyInspection(
|
||||
messageKey = "HHH000277",
|
||||
logger = @Logger( loggerNameClass = SessionFactoryRegistry.class )
|
||||
)
|
||||
public class SessionFactoryNamingTests {
|
||||
@Test
|
||||
@DomainModel
|
||||
@ServiceRegistry( settings = {
|
||||
@Setting( name = AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, value = "true" ),
|
||||
@Setting( name = AvailableSettings.SESSION_FACTORY_JNDI_NAME, value = "jndi-named" )
|
||||
} )
|
||||
@SessionFactory()
|
||||
void testExplicitJndiName(SessionFactoryScope scope, MessageKeyWatcher logWatcher) {
|
||||
scope.getSessionFactory();
|
||||
assertThat( logWatcher.wasTriggered() ).isTrue();
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@Test
|
||||
@DomainModel
|
||||
@ServiceRegistry( settings = @Setting( name = AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, value = "true" ) )
|
||||
@SessionFactory( sessionFactoryName = "named" )
|
||||
void testSessionFactoryName(SessionFactoryScope scope, MessageKeyWatcher logWatcher) {
|
||||
scope.getSessionFactory();
|
||||
assertThat( logWatcher.wasTriggered() ).isTrue();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DomainModel
|
||||
@ServiceRegistry( settings = @Setting( name = AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, value = "false" ) )
|
||||
@SessionFactory( sessionFactoryName = "named" )
|
||||
void testNonJndiSessionFactoryName(SessionFactoryScope scope, MessageKeyWatcher logWatcher) {
|
||||
scope.getSessionFactory();
|
||||
assertThat( logWatcher.wasTriggered() ).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DomainModel
|
||||
@ServiceRegistry( settings = {
|
||||
@Setting( name = AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, value = "true" ),
|
||||
// mimics the persistence.xml persistence-unit name
|
||||
@Setting( name = PersistenceSettings.PERSISTENCE_UNIT_NAME, value = "named-pu" ),
|
||||
} )
|
||||
@SessionFactory
|
||||
void testPuName(SessionFactoryScope scope, MessageKeyWatcher logWatcher) {
|
||||
scope.getSessionFactory();
|
||||
assertThat( logWatcher.wasTriggered() ).isFalse();
|
||||
}
|
||||
|
||||
@Test
|
||||
@DomainModel
|
||||
@ServiceRegistry( settings = {
|
||||
@Setting( name = AvailableSettings.SESSION_FACTORY_NAME_IS_JNDI, value = "false" ),
|
||||
// mimics the persistence.xml persistence-unit name
|
||||
@Setting( name = PersistenceSettings.PERSISTENCE_UNIT_NAME, value = "named-pu" ),
|
||||
} )
|
||||
@SessionFactory
|
||||
void testNonJndiPuName(SessionFactoryScope scope, MessageKeyWatcher logWatcher) {
|
||||
scope.getSessionFactory();
|
||||
assertThat( logWatcher.wasTriggered() ).isFalse();
|
||||
}
|
||||
}
|
|
@ -45,12 +45,12 @@ public class SessionFactorySerializationTest extends BaseUnitTestCase {
|
|||
// different VM
|
||||
String uuid = ( (SessionFactoryImplementor) factory ).getUuid();
|
||||
// deregister under this uuid...
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( uuid, NAME, false, null );
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( uuid, NAME, null, null );
|
||||
// and then register under a different uuid...
|
||||
SessionFactoryRegistry.INSTANCE.addSessionFactory(
|
||||
"some-other-uuid",
|
||||
NAME,
|
||||
false,
|
||||
null,
|
||||
(SessionFactoryImplementor) factory,
|
||||
null
|
||||
);
|
||||
|
@ -58,7 +58,7 @@ public class SessionFactorySerializationTest extends BaseUnitTestCase {
|
|||
SessionFactory factory2 = (SessionFactory) SerializationHelper.clone( factory );
|
||||
assertSame( factory, factory2 );
|
||||
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( "some-other-uuid", NAME, false, null );
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( "some-other-uuid", NAME, null, null );
|
||||
}
|
||||
|
||||
assertFalse( SessionFactoryRegistry.INSTANCE.hasRegistrations() );
|
||||
|
@ -77,12 +77,12 @@ public class SessionFactorySerializationTest extends BaseUnitTestCase {
|
|||
// different VM
|
||||
String uuid = ( (SessionFactoryImplementor) factory ).getUuid();
|
||||
// deregister under this uuid...
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( uuid, null, false, null );
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( uuid, null, null, null );
|
||||
// and then register under a different uuid...
|
||||
SessionFactoryRegistry.INSTANCE.addSessionFactory(
|
||||
"some-other-uuid",
|
||||
null,
|
||||
false,
|
||||
null,
|
||||
(SessionFactoryImplementor) factory,
|
||||
null
|
||||
);
|
||||
|
@ -94,7 +94,7 @@ public class SessionFactorySerializationTest extends BaseUnitTestCase {
|
|||
catch (SerializationException expected) {
|
||||
}
|
||||
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( "some-other-uuid", null, false, null );
|
||||
SessionFactoryRegistry.INSTANCE.removeSessionFactory( "some-other-uuid", null, null, null );
|
||||
}
|
||||
|
||||
assertFalse( SessionFactoryRegistry.INSTANCE.hasRegistrations() );
|
||||
|
|
|
@ -0,0 +1,17 @@
|
|||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<!--
|
||||
~ 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>.
|
||||
-->
|
||||
|
||||
<!-- example of reference to a cfg.xml file -->
|
||||
<persistence xmlns="http://java.sun.com/xml/ns/persistence"
|
||||
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
|
||||
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd"
|
||||
version="1.0">
|
||||
<persistence-unit name="named-session-factory" transaction-type="RESOURCE_LOCAL">
|
||||
<provider>org.hibernate.jpa.HibernatePersistenceProvider</provider>
|
||||
</persistence-unit>
|
||||
</persistence>
|
|
@ -137,6 +137,33 @@ String isDefault();
|
|||
The default precision for Oracle timestamps was changed to 9 i.e. nanosecond precision.
|
||||
The default precision for SQL Server timestamps was changed to 7 i.e. 100 nanosecond precision.
|
||||
|
||||
|
||||
[[sf-name]]
|
||||
== SessionFactory Name (and JNDI)
|
||||
|
||||
Hibernate defines `SessionFactory#getName` (specified via `cfg.xml` or `hibernate.session_factory_name`) which is used to
|
||||
help with (de)serializing a `SessionFactory`. It is also, unless `hibernate.session_factory_name_is_jndi` is set to `false`,
|
||||
used in biding the `SessionFactory` into JNDI.
|
||||
|
||||
This `SessionFactory#getName` method pre-dates Jakarta Persistence (and JPA). It now implements `EntityManagerFactory#getName`
|
||||
inherited from Jakarta Persistence, which states that this name should come from the persistence-unit name.
|
||||
To align with Jakarta Persistence (the 3.2 TCK tests this), Hibernate now considers the persistence-unit name if no
|
||||
`hibernate.session_factory_name` is specified.
|
||||
|
||||
However, because `hibernate.session_factory_name` is also a trigger to attempt to bind the SessionFactory into JNDI,
|
||||
this change to consider persistence-unit name, means that each `SessionFactory` created through Jakarta Persistence now
|
||||
have a name and Hibernate attempted to bind these to JNDI.
|
||||
|
||||
To work around this we have introduced a new `hibernate.session_factory_jndi_name` setting that can be used to explicitly
|
||||
specify a name for JNDI binding. The new behavior is as follows (assuming `hibernate.session_factory_name_is_jndi` is not explicitly configured):
|
||||
|
||||
* If `hibernate.session_factory_jndi_name` is specified, the name is used to bind into JNDI
|
||||
* If `hibernate.session_factory_name` is specified, the name is used to bind into JNDI
|
||||
|
||||
Hibernate can use the persistence-unit name for binding into JNDI as well, but `hibernate.session_factory_name_is_jndi`
|
||||
must be explicitly set to true.
|
||||
|
||||
|
||||
[[todo]]
|
||||
== Todos (dev)
|
||||
|
||||
|
|
Loading…
Reference in New Issue