Skip to content

HHH-17154 Fix NullPointerException is thrown when constructing EntityManagerFactoryBuilderImpl #7264

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Sep 1, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -167,9 +167,14 @@ public void discoverTypes(String className, byte[] originalBytes) {
if ( originalBytes != null ) {
classFileLocator.setClassNameAndBytes( className, originalBytes );
}
final TypeDescription typeDescription = typePool.describe( className ).resolve();
enhancementContext.registerDiscoveredType( typeDescription, Type.PersistenceType.ENTITY );
enhancementContext.discoverCompositeTypes( typeDescription, typePool );
try {
final TypeDescription typeDescription = typePool.describe( className ).resolve();
enhancementContext.registerDiscoveredType( typeDescription, Type.PersistenceType.ENTITY );
enhancementContext.discoverCompositeTypes( typeDescription, typePool );
}
catch (RuntimeException e) {
throw new EnhancementException( "Failed to discover types for class " + className, e );
}
}

private TypePool buildTypePool(final ClassFileLocator classFileLocator) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -31,5 +31,16 @@ public interface Enhancer {
*/
byte[] enhance(String className, byte[] originalBytes) throws EnhancementException;

void discoverTypes(String className, byte[] originalBytes);
/**
* Discovers types prior to enhancement.
*
* It is possible to invoke this method concurrently.
*
* @param className The name of the class whose bytecode is being analyzed for type discovery.
* @param originalBytes The class's original (pre-enhancement) byte code
*
* @throws EnhancementException Indicates a problem during type discovery
* @since 6.3
*/
void discoverTypes(String className, byte[] originalBytes) throws EnhancementException;
}
Original file line number Diff line number Diff line change
Expand Up @@ -43,5 +43,5 @@ byte[] transform(
ProtectionDomain protectionDomain,
byte[] classfileBuffer) throws TransformerException;

void discoverTypes(ClassLoader loader, String entityClassName);
void discoverTypes(ClassLoader loader, String className);
}
Original file line number Diff line number Diff line change
Expand Up @@ -1861,4 +1861,9 @@ void attemptToAssociateProxyWithTwoOpenSessions(
id = 515)
HibernateException nullIdentitySelectString();

@LogMessage(level = WARN)
@Message(value = "Failed to discover types for enhancement from class: %s",
id = 516)
void enhancementDiscoveryFailed(String className, @Cause Throwable cause);

}
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,10 @@
import org.hibernate.boot.cfgxml.spi.CfgXmlAccessService;
import org.hibernate.boot.cfgxml.spi.LoadedConfig;
import org.hibernate.boot.cfgxml.spi.MappingReference;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmHibernateMapping;
import org.hibernate.boot.jaxb.hbm.spi.JaxbHbmRootEntityType;
import org.hibernate.boot.jaxb.spi.BindableMappingDescriptor;
import org.hibernate.boot.jaxb.spi.Binding;
import org.hibernate.boot.model.TypeContributor;
import org.hibernate.boot.model.convert.internal.ClassBasedConverterDescriptor;
import org.hibernate.boot.model.convert.spi.ConverterDescriptor;
Expand All @@ -50,6 +54,7 @@
import org.hibernate.boot.spi.SessionFactoryBuilderImplementor;
import org.hibernate.bytecode.enhance.spi.DefaultEnhancementContext;
import org.hibernate.bytecode.enhance.spi.EnhancementContext;
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.ClassTransformer;
Expand Down Expand Up @@ -347,11 +352,34 @@ private EntityManagerFactoryBuilderImpl(
if ( classLoader == null ) {
throw persistenceException( "Enhancement requires a temp class loader, but none was given." );
}
for ( PersistentClass entityBinding : metadata.getEntityBindings() ) {
if ( entityBinding.getClassName() != null ) {
classTransformer.discoverTypes( classLoader, entityBinding.getClassName() );
for ( Binding<BindableMappingDescriptor> binding : metadataSources.getXmlBindings() ) {
final BindableMappingDescriptor root = binding.getRoot();
if ( root instanceof JaxbHbmHibernateMapping ) {
final JaxbHbmHibernateMapping hibernateMapping = (JaxbHbmHibernateMapping) root;
final String packageName = hibernateMapping.getPackage();
for ( JaxbHbmRootEntityType clazz : hibernateMapping.getClazz() ) {
final String className;
if ( packageName == null || packageName.isEmpty() ) {
className = clazz.getName();
}
else {
className = packageName + '.' + clazz.getName();
}
try {
classTransformer.discoverTypes( classLoader, className );
}
catch (EnhancementException ex) {
LOG.enhancementDiscoveryFailed( className, ex );
}
}
}
}
for ( String annotatedClassName : metadataSources.getAnnotatedClassNames() ) {
classTransformer.discoverTypes( classLoader, annotatedClassName );
}
for ( Class<?> annotatedClass : metadataSources.getAnnotatedClasses() ) {
classTransformer.discoverTypes( classLoader, annotatedClass.getName() );
}
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -57,8 +57,8 @@ public byte[] transform(
}

@Override
public void discoverTypes(ClassLoader loader, String entityClassName) {
getEnhancer( loader ).discoverTypes( entityClassName, null );
public void discoverTypes(ClassLoader loader, String className) {
getEnhancer( loader ).discoverTypes( className, null );
}

private Enhancer getEnhancer(ClassLoader loader) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -42,11 +42,13 @@
import org.hibernate.jpa.HibernatePersistenceProvider;
import org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl;
import org.hibernate.jpa.boot.internal.PersistenceUnitInfoDescriptor;
import org.hibernate.jpa.boot.spi.EntityManagerFactoryBuilder;
import org.hibernate.orm.test.mapping.basic.bitset.BitSetType;
import org.hibernate.orm.test.mapping.basic.bitset.BitSetUserType;
import org.hibernate.service.ServiceRegistry;
import org.hibernate.service.spi.SessionFactoryServiceRegistry;

import org.hibernate.testing.orm.junit.JiraKey;
import org.junit.Test;

import jakarta.persistence.AttributeConverter;
Expand Down Expand Up @@ -322,6 +324,22 @@ public void test_bootstrap_bootstrap_native_EntityManagerFactory_example() {
}
}

@Test
@JiraKey("HHH-17154")
public void build_EntityManagerFactory_with_NewTempClassLoader() {
new EntityManagerFactoryBuilderImpl(
new PersistenceUnitInfoDescriptor(
new PersistenceUnitInfoImpl( "", new ArrayList<>(), new Properties() ) {
@Override
public ClassLoader getNewTempClassLoader() {
return Thread.currentThread().getContextClassLoader();
}
}
),
new HashMap<>()
).cancel();
}

public Object getBeanManager() {
return null;
}
Expand Down