Skip to content

Commit 87ba94d

Browse files
committed
Allow configuration of EntityManagerFactoryBuilderImpl to override the BytecodeProvider instance
1 parent 2da013e commit 87ba94d

File tree

4 files changed

+41
-1
lines changed

4 files changed

+41
-1
lines changed

hibernate-core/src/main/java/org/hibernate/bytecode/enhance/spi/EnhancementContext.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
*/
77
package org.hibernate.bytecode.enhance.spi;
88

9+
import org.hibernate.bytecode.spi.BytecodeProvider;
10+
911
import jakarta.persistence.metamodel.Type;
1012
import org.hibernate.Incubating;
1113

@@ -158,4 +160,15 @@ public interface EnhancementContext {
158160
default UnsupportedEnhancementStrategy getUnsupportedEnhancementStrategy() {
159161
return UnsupportedEnhancementStrategy.SKIP;
160162
}
163+
164+
/**
165+
* Allows to force the use of a specific instance of BytecodeProvider to perform the enhancement.
166+
* @return When returning {code null} the default implementation will be used. Only return a different instance if
167+
* you need to override the default implementation.
168+
*/
169+
@Incubating
170+
default BytecodeProvider getBytecodeProvider() {
171+
return null;
172+
}
173+
161174
}

hibernate-core/src/main/java/org/hibernate/cfg/BytecodeSettings.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,17 @@ public interface BytecodeSettings {
2828
@Deprecated( forRemoval = true )
2929
String BYTECODE_PROVIDER = "hibernate.bytecode.provider";
3030

31+
/**
32+
* This is similar to the now deprecated legacy property {@code hibernate.bytecode.provider} except
33+
* it's used specifically to pass an existing instance of a {@link org.hibernate.bytecode.spi.BytecodeProvider};
34+
* this happens to also allow to override the implementation, but is primarily intended to allow reusing a
35+
* specific instance; this could be useful when the implementation benefits from internal caches.
36+
* When not set, Hibernate will create its default implementation.
37+
*
38+
* @settingDefault {@code null}
39+
*/
40+
String BYTECODE_PROVIDER_INSTANCE = "hibernate.enhancer.bytecodeprovider.instance";
41+
3142
/**
3243
* Enable association management feature in runtime bytecode enhancement
3344
*

hibernate-core/src/main/java/org/hibernate/jpa/boot/internal/EntityManagerFactoryBuilderImpl.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
import org.hibernate.bytecode.enhance.spi.EnhancementException;
5858
import org.hibernate.bytecode.enhance.spi.UnloadedClass;
5959
import org.hibernate.bytecode.enhance.spi.UnloadedField;
60+
import org.hibernate.bytecode.spi.BytecodeProvider;
6061
import org.hibernate.bytecode.spi.ClassTransformer;
6162
import org.hibernate.cfg.AvailableSettings;
6263
import org.hibernate.cfg.Environment;
@@ -128,6 +129,7 @@
128129
import static org.hibernate.cfg.AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY;
129130
import static org.hibernate.cfg.AvailableSettings.URL;
130131
import static org.hibernate.cfg.AvailableSettings.USER;
132+
import static org.hibernate.cfg.BytecodeSettings.BYTECODE_PROVIDER_INSTANCE;
131133
import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT;
132134
import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_DIRTY_TRACKING;
133135
import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_LAZY_INITIALIZATION;
@@ -337,6 +339,7 @@ private EntityManagerFactoryBuilderImpl(
337339

338340
if ( dirtyTrackingEnabled || lazyInitializationEnabled || associationManagementEnabled ) {
339341
EnhancementContext enhancementContext = getEnhancementContext(
342+
configurationValues,
340343
dirtyTrackingEnabled,
341344
lazyInitializationEnabled,
342345
associationManagementEnabled
@@ -434,15 +437,23 @@ private boolean readBooleanConfigurationValue(String propertyName) {
434437
/**
435438
* Builds the context to be used in runtime bytecode enhancement
436439
*
440+
* @param configurationValues
437441
* @param dirtyTrackingEnabled To enable dirty tracking feature
438442
* @param lazyInitializationEnabled To enable lazy initialization feature
439443
* @param associationManagementEnabled To enable association management feature
444+
*
440445
* @return An enhancement context for classes managed by this EM
441446
*/
442447
protected EnhancementContext getEnhancementContext(
448+
Map<String, Object> configurationValues,
443449
final boolean dirtyTrackingEnabled,
444450
final boolean lazyInitializationEnabled,
445451
final boolean associationManagementEnabled ) {
452+
final Object propValue = configurationValues.get( BYTECODE_PROVIDER_INSTANCE );
453+
if ( propValue != null && ( ! ( propValue instanceof BytecodeProvider ) ) ) {
454+
throw persistenceException( "Property " + BYTECODE_PROVIDER_INSTANCE + " was set to '" + propValue + "', which is not compatible with the expected type " + BytecodeProvider.class );
455+
}
456+
final BytecodeProvider overriddenBytecodeProvider = (BytecodeProvider) propValue;
446457
return new DefaultEnhancementContext() {
447458

448459
@Override
@@ -483,6 +494,10 @@ public boolean doExtendedEnhancement(UnloadedClass classDescriptor) {
483494
return false;
484495
}
485496

497+
@Override
498+
public BytecodeProvider getBytecodeProvider() {
499+
return overriddenBytecodeProvider;
500+
}
486501
};
487502
}
488503

hibernate-core/src/main/java/org/hibernate/jpa/internal/enhance/EnhancingClassTransformerImpl.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ public class EnhancingClassTransformerImpl implements ClassTransformer {
3737
public EnhancingClassTransformerImpl(EnhancementContext enhancementContext) {
3838
Objects.requireNonNull( enhancementContext );
3939
this.enhancementContext = enhancementContext;
40-
this.bytecodeProvider = BytecodeProviderInitiator.buildDefaultBytecodeProvider();
40+
final BytecodeProvider overriddenProvider = enhancementContext.getBytecodeProvider();
41+
this.bytecodeProvider = overriddenProvider == null ? BytecodeProviderInitiator.buildDefaultBytecodeProvider() : overriddenProvider;
4142
}
4243

4344
@Override

0 commit comments

Comments
 (0)