Skip to content

Commit

Permalink
HHH-19050 Allow configuration of EntityManagerFactoryBuilderImpl to o…
Browse files Browse the repository at this point in the history
…verride the BytecodeProvider instance
  • Loading branch information
Sanne committed Jan 17, 2025
1 parent 2da013e commit ecb4c18
Show file tree
Hide file tree
Showing 4 changed files with 41 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
*/
package org.hibernate.bytecode.enhance.spi;

import org.hibernate.bytecode.spi.BytecodeProvider;

import jakarta.persistence.metamodel.Type;
import org.hibernate.Incubating;

Expand Down Expand Up @@ -158,4 +160,15 @@ public interface EnhancementContext {
default UnsupportedEnhancementStrategy getUnsupportedEnhancementStrategy() {
return UnsupportedEnhancementStrategy.SKIP;
}

/**
* Allows to force the use of a specific instance of BytecodeProvider to perform the enhancement.
* @return When returning {code null} the default implementation will be used. Only return a different instance if
* you need to override the default implementation.
*/
@Incubating
default BytecodeProvider getBytecodeProvider() {
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,17 @@ public interface BytecodeSettings {
@Deprecated( forRemoval = true )
String BYTECODE_PROVIDER = "hibernate.bytecode.provider";

/**
* This is similar to the now deprecated legacy property {@code hibernate.bytecode.provider} except
* it's used specifically to pass an existing instance of a {@link org.hibernate.bytecode.spi.BytecodeProvider};
* this happens to also allow to override the implementation, but is primarily intended to allow reusing a
* specific instance; this could be useful when the implementation benefits from internal caches.
* When not set, Hibernate will create its default implementation.
*
* @settingDefault {@code null}
*/
String BYTECODE_PROVIDER_INSTANCE = "hibernate.enhancer.bytecodeprovider.instance";

/**
* Enable association management feature in runtime bytecode enhancement
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@
import org.hibernate.bytecode.enhance.spi.EnhancementException;
import org.hibernate.bytecode.enhance.spi.UnloadedClass;
import org.hibernate.bytecode.enhance.spi.UnloadedField;
import org.hibernate.bytecode.spi.BytecodeProvider;
import org.hibernate.bytecode.spi.ClassTransformer;
import org.hibernate.cfg.AvailableSettings;
import org.hibernate.cfg.Environment;
Expand Down Expand Up @@ -128,6 +129,7 @@
import static org.hibernate.cfg.AvailableSettings.TRANSACTION_COORDINATOR_STRATEGY;
import static org.hibernate.cfg.AvailableSettings.URL;
import static org.hibernate.cfg.AvailableSettings.USER;
import static org.hibernate.cfg.BytecodeSettings.BYTECODE_PROVIDER_INSTANCE;
import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_ASSOCIATION_MANAGEMENT;
import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_DIRTY_TRACKING;
import static org.hibernate.cfg.BytecodeSettings.ENHANCER_ENABLE_LAZY_INITIALIZATION;
Expand Down Expand Up @@ -337,6 +339,7 @@ private EntityManagerFactoryBuilderImpl(

if ( dirtyTrackingEnabled || lazyInitializationEnabled || associationManagementEnabled ) {
EnhancementContext enhancementContext = getEnhancementContext(
configurationValues,
dirtyTrackingEnabled,
lazyInitializationEnabled,
associationManagementEnabled
Expand Down Expand Up @@ -434,15 +437,23 @@ private boolean readBooleanConfigurationValue(String propertyName) {
/**
* Builds the context to be used in runtime bytecode enhancement
*
* @param configurationValues
* @param dirtyTrackingEnabled To enable dirty tracking feature
* @param lazyInitializationEnabled To enable lazy initialization feature
* @param associationManagementEnabled To enable association management feature
*
* @return An enhancement context for classes managed by this EM
*/
protected EnhancementContext getEnhancementContext(
Map<String, Object> configurationValues,
final boolean dirtyTrackingEnabled,
final boolean lazyInitializationEnabled,
final boolean associationManagementEnabled ) {
final Object propValue = configurationValues.get( BYTECODE_PROVIDER_INSTANCE );
if ( propValue != null && ( ! ( propValue instanceof BytecodeProvider ) ) ) {
throw persistenceException( "Property " + BYTECODE_PROVIDER_INSTANCE + " was set to '" + propValue + "', which is not compatible with the expected type " + BytecodeProvider.class );
}
final BytecodeProvider overriddenBytecodeProvider = (BytecodeProvider) propValue;
return new DefaultEnhancementContext() {

@Override
Expand Down Expand Up @@ -483,6 +494,10 @@ public boolean doExtendedEnhancement(UnloadedClass classDescriptor) {
return false;
}

@Override
public BytecodeProvider getBytecodeProvider() {
return overriddenBytecodeProvider;
}
};
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,8 @@ public class EnhancingClassTransformerImpl implements ClassTransformer {
public EnhancingClassTransformerImpl(EnhancementContext enhancementContext) {
Objects.requireNonNull( enhancementContext );
this.enhancementContext = enhancementContext;
this.bytecodeProvider = BytecodeProviderInitiator.buildDefaultBytecodeProvider();
final BytecodeProvider overriddenProvider = enhancementContext.getBytecodeProvider();
this.bytecodeProvider = overriddenProvider == null ? BytecodeProviderInitiator.buildDefaultBytecodeProvider() : overriddenProvider;
}

@Override
Expand Down

0 comments on commit ecb4c18

Please sign in to comment.