Skip to content

Commit 48f0122

Browse files
committed
HHH-19849 Add an SPI that allows attaching session-scoped "extensions" to the session/statelesssession implementors
1 parent 38777d8 commit 48f0122

13 files changed

+287
-1
lines changed
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.engine.extension.internal;
6+
7+
import org.hibernate.boot.registry.classloading.spi.ClassLoaderService;
8+
import org.hibernate.engine.extension.spi.ExtensionIntegration;
9+
import org.hibernate.engine.extension.spi.ExtensionIntegrationService;
10+
import org.jboss.logging.Logger;
11+
12+
import java.util.LinkedHashSet;
13+
import java.util.Set;
14+
15+
public class ExtensionIntegrationServiceImpl implements ExtensionIntegrationService {
16+
17+
private static final Logger LOG = Logger.getLogger( ExtensionIntegrationServiceImpl.class );
18+
19+
private final LinkedHashSet<ExtensionIntegration<?>> integrators = new LinkedHashSet<>();
20+
21+
private ExtensionIntegrationServiceImpl() {
22+
}
23+
24+
public static ExtensionIntegrationServiceImpl create(Set<ExtensionIntegration<?>> integrations, ClassLoaderService classLoaderService) {
25+
ExtensionIntegrationServiceImpl instance = new ExtensionIntegrationServiceImpl();
26+
27+
// register provided integrators
28+
for ( ExtensionIntegration<?> integration : integrations ) {
29+
instance.addExtensionIntegration( integration );
30+
}
31+
for ( ExtensionIntegration<?> integration : classLoaderService.loadJavaServices(
32+
ExtensionIntegration.class ) ) {
33+
instance.addExtensionIntegration( integration );
34+
}
35+
36+
return instance;
37+
}
38+
39+
private void addExtensionIntegration(ExtensionIntegration<?> integration) {
40+
if ( LOG.isDebugEnabled() ) {
41+
LOG.debugf( "Adding extension integration for [%s]", integration.getExtensionType().getName() );
42+
}
43+
integrators.add( integration );
44+
}
45+
46+
@Override
47+
public Iterable<ExtensionIntegration<?>> extensionIntegrations() {
48+
return integrators;
49+
}
50+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.engine.extension.spi;
6+
7+
import org.hibernate.Incubating;
8+
9+
/// A marker interface for Session extensions.
10+
@Incubating
11+
public interface Extension {
12+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.engine.extension.spi;
6+
7+
import org.hibernate.Incubating;
8+
9+
@Incubating
10+
public interface ExtensionIntegration<E extends Extension> {
11+
Class<E> getExtensionType();
12+
13+
E createExtension(ExtensionIntegrationContext context);
14+
}
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.engine.extension.spi;
6+
7+
import org.hibernate.Incubating;
8+
import org.hibernate.engine.spi.SharedSessionContractImplementor;
9+
10+
@Incubating
11+
public interface ExtensionIntegrationContext {
12+
13+
SharedSessionContractImplementor getSession();
14+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.engine.extension.spi;
6+
7+
import org.hibernate.Incubating;
8+
import org.hibernate.service.Service;
9+
10+
@Incubating
11+
public interface ExtensionIntegrationService extends Service {
12+
/**
13+
* Retrieve all extensions.
14+
*
15+
* @return All extensions.
16+
*/
17+
Iterable<ExtensionIntegration<?>> extensionIntegrations();
18+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
/*
2+
* SPDX-License-Identifier: Apache-2.0
3+
* Copyright Red Hat Inc. and Hibernate Authors
4+
*/
5+
package org.hibernate.engine.extension.spi;
6+
7+
import org.hibernate.Incubating;
8+
import org.hibernate.engine.extension.internal.ExtensionIntegrationServiceImpl;
9+
import org.hibernate.service.spi.SessionFactoryServiceInitiator;
10+
import org.hibernate.service.spi.SessionFactoryServiceInitiatorContext;
11+
12+
import java.util.Set;
13+
14+
@Incubating
15+
public class ExtensionIntegrationServiceInitiator
16+
implements SessionFactoryServiceInitiator<ExtensionIntegrationService> {
17+
18+
public static final ExtensionIntegrationServiceInitiator INSTANCE = new ExtensionIntegrationServiceInitiator();
19+
20+
@Override
21+
public ExtensionIntegrationService initiateService(SessionFactoryServiceInitiatorContext context) {
22+
return ExtensionIntegrationServiceImpl.create( Set.of(), context.getSessionFactory().getClassLoaderService() );
23+
}
24+
25+
@Override
26+
public Class<ExtensionIntegrationService> getServiceInitiated() {
27+
return ExtensionIntegrationService.class;
28+
}
29+
}
Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
/**
2+
* This package contains an SPI for Session extensions.
3+
*/
4+
@Incubating
5+
package org.hibernate.engine.extension.spi;
6+
7+
import org.hibernate.Incubating;

hibernate-core/src/main/java/org/hibernate/engine/spi/SessionDelegatorBaseImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@
4343
import org.hibernate.bytecode.enhance.spi.interceptor.SessionAssociationMarkers;
4444
import org.hibernate.cache.spi.CacheTransactionSynchronization;
4545
import org.hibernate.collection.spi.PersistentCollection;
46+
import org.hibernate.engine.extension.spi.Extension;
4647
import org.hibernate.engine.jdbc.LobCreator;
4748
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
4849
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
@@ -517,6 +518,11 @@ public RootGraphImplementor<?> getEntityGraph(String graphName) {
517518
return delegate.getEntityGraph( graphName );
518519
}
519520

521+
@Override
522+
public <T extends Extension> T getExtension(Class<T> extension) {
523+
return delegate.getExtension( extension );
524+
}
525+
520526
@Override
521527
public <T> QueryImplementor<T> createQuery(CriteriaSelect<T> selectQuery) {
522528
return delegate.createQuery( selectQuery );

hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionContractImplementor.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66

77
import java.util.Set;
88
import java.util.UUID;
9+
910
import jakarta.persistence.TransactionRequiredException;
1011
import org.checkerframework.checker.nullness.qual.Nullable;
1112

@@ -18,6 +19,7 @@
1819
import org.hibernate.StatelessSession;
1920
import org.hibernate.bytecode.enhance.spi.interceptor.SessionAssociationMarkers;
2021
import org.hibernate.dialect.Dialect;
22+
import org.hibernate.engine.extension.spi.Extension;
2123
import org.hibernate.event.spi.EventSource;
2224
import org.hibernate.graph.spi.RootGraphImplementor;
2325
import org.hibernate.query.Query;
@@ -621,4 +623,17 @@ default boolean isStatelessSession() {
621623

622624
@Override
623625
RootGraphImplementor<?> getEntityGraph(String graphName);
626+
627+
/**
628+
* Allows accessing session scoped extension storages of the particular session instance.
629+
* <p>
630+
* Extensions first had to be registered with the {@link org.hibernate.SessionFactory}
631+
*
632+
* @param extension The extension storage attached to the current session.
633+
* if the current session does not yet have the particular storage type attached to this session.
634+
* @param <E> The type of the extension storage.
635+
*/
636+
@Incubating
637+
<E extends Extension> E getExtension(Class<E> extension);
638+
624639
}

hibernate-core/src/main/java/org/hibernate/engine/spi/SharedSessionDelegatorBaseImpl.java

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import org.hibernate.bytecode.enhance.spi.interceptor.SessionAssociationMarkers;
2525
import org.hibernate.cache.spi.CacheTransactionSynchronization;
2626
import org.hibernate.collection.spi.PersistentCollection;
27+
import org.hibernate.engine.extension.spi.Extension;
2728
import org.hibernate.engine.jdbc.LobCreator;
2829
import org.hibernate.engine.jdbc.connections.spi.JdbcConnectionAccess;
2930
import org.hibernate.engine.jdbc.spi.JdbcCoordinator;
@@ -663,6 +664,11 @@ public RootGraphImplementor<?> getEntityGraph(String graphName) {
663664
return delegate.getEntityGraph( graphName );
664665
}
665666

667+
@Override
668+
public <T extends Extension> T getExtension(Class<T> extension) {
669+
return delegate.getExtension( extension);
670+
}
671+
666672
@Override
667673
public <T> List<EntityGraph<? super T>> getEntityGraphs(Class<T> entityClass) {
668674
return delegate.getEntityGraphs( entityClass );

0 commit comments

Comments
 (0)