diff --git a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
index fe4992b659..6503cbe399 100644
--- a/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
+++ b/hibernate-core/src/main/java/org/hibernate/SessionFactory.java
@@ -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.
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java
index bdb908ac9d..478e3e09f0 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/SessionFactoryBuilder.java
@@ -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);
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryObserverForRegistration.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryObserverForRegistration.java
index 338ad64cd6..1169e1d9dc 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryObserverForRegistration.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryObserverForRegistration.java
@@ -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
);
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java
index 234a4954ae..f3b3038e98 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/internal/SessionFactoryOptionsBuilder.java
@@ -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;
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java
index 777fb0194c..361c508da8 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/AbstractDelegatingSessionFactoryOptions.java
@@ -101,7 +101,7 @@ public class AbstractDelegatingSessionFactoryOptions implements SessionFactoryOp
}
@Override
- public boolean isSessionFactoryNameAlsoJndiName() {
+ public Boolean isSessionFactoryNameAlsoJndiName() {
return delegate.isSessionFactoryNameAlsoJndiName();
}
diff --git a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java
index d983eb79e7..1fb1920580 100644
--- a/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java
+++ b/hibernate-core/src/main/java/org/hibernate/boot/spi/SessionFactoryOptions.java
@@ -85,10 +85,10 @@ public interface SessionFactoryOptions extends QueryEngineOptions {
}
/**
- * The name to be used for the SessionFactory. This is used both in:
- *
in-VM serialization
- *
JNDI binding, depending on {@link #isSessionFactoryNameAlsoJndiName}
- *
+ * 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();
diff --git a/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java b/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java
index f6ef51c52d..065630d9fb 100644
--- a/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java
+++ b/hibernate-core/src/main/java/org/hibernate/cfg/PersistenceSettings.java
@@ -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.
*
- * 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.
+ *
+ * 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";
diff --git a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java
index e81a326d5a..3721d004e1 100644
--- a/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/engine/spi/SessionFactoryDelegatingImpl.java
@@ -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();
diff --git a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java
index f4713dca41..343d9238fd 100644
--- a/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java
+++ b/hibernate-core/src/main/java/org/hibernate/internal/SessionFactoryImpl.java
@@ -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 settings) {
+ private static void deprecationCheck(Map 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