Skip to content

HHH-19372 HHH-19369 Issues with access optimizer and inheritance #10075

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

Draft
wants to merge 7 commits into
base: main
Choose a base branch
from
Original file line number Diff line number Diff line change
Expand Up @@ -104,6 +104,7 @@
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Locale;
import java.util.Map;
Expand Down Expand Up @@ -145,7 +146,7 @@ public class InFlightMetadataCollectorImpl

private final UUID uuid;

private final Map<String,PersistentClass> entityBindingMap = new HashMap<>();
private final Map<String,PersistentClass> entityBindingMap = new LinkedHashMap<>();
private final List<Component> composites = new ArrayList<>();
private final Map<Class<?>, Component> genericComponentsMap = new HashMap<>();
private final Map<ClassDetails, List<ClassDetails>> embeddableSubtypes = new HashMap<>();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@

import net.bytebuddy.description.modifier.Visibility;
import net.bytebuddy.dynamic.scaffold.subclass.ConstructorStrategy;
import org.hibernate.proxy.pojo.bytebuddy.ByteBuddyProxyHelper;

public class BasicProxyFactoryImpl implements BasicProxyFactory {

Expand All @@ -36,7 +37,7 @@ public BasicProxyFactoryImpl(final Class superClass, final Class interfaceClass,

final Class<?> superClassOrMainInterface = superClass != null ? superClass : interfaceClass;
final ByteBuddyState.ProxyDefinitionHelpers helpers = byteBuddyState.getProxyDefinitionHelpers();
final String proxyClassName = superClassOrMainInterface.getName() + "$" + PROXY_NAMING_SUFFIX;
final String proxyClassName = ByteBuddyProxyHelper.getClassNameWithSuffix( superClassOrMainInterface, PROXY_NAMING_SUFFIX );

this.proxyClass = byteBuddyState.loadBasicProxy( superClassOrMainInterface, proxyClassName, (byteBuddy, namingStrategy) ->
helpers.appendIgnoreAlsoAtEnd( byteBuddy
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -148,7 +148,7 @@ public ReflectionOptimizer getReflectionOptimizer(
fastClass = null;
}
else {
final String className = clazz.getName() + "$" + INSTANTIATOR_PROXY_NAMING_SUFFIX;
final String className = ByteBuddyProxyHelper.getClassNameWithSuffix( clazz, INSTANTIATOR_PROXY_NAMING_SUFFIX );
fastClass = byteBuddyState.load( clazz, className, (byteBuddy, namingStrategy) -> byteBuddy
.with( namingStrategy )
.subclass( ReflectionOptimizer.InstantiationOptimizer.class )
Expand Down Expand Up @@ -210,7 +210,7 @@ public ReflectionOptimizer getReflectionOptimizer(
fastClass = null;
}
else {
final String className = clazz.getName() + "$" + INSTANTIATOR_PROXY_NAMING_SUFFIX;
final String className = ByteBuddyProxyHelper.getClassNameWithSuffix( clazz, INSTANTIATOR_PROXY_NAMING_SUFFIX );
fastClass = byteBuddyState.load( clazz, className, (byteBuddy, namingStrategy) -> byteBuddy
.with( namingStrategy )
.subclass( ReflectionOptimizer.InstantiationOptimizer.class )
Expand All @@ -236,7 +236,8 @@ public ReflectionOptimizer getReflectionOptimizer(
final String[] propertyNames = propertyAccessMap.keySet().toArray( new String[0] );
final Class<?> superClass = determineAccessOptimizerSuperClass( clazz, propertyNames, getters, setters );

final String className = clazz.getName() + "$" + OPTIMIZER_PROXY_NAMING_SUFFIX + encodeName( propertyNames, getters, setters );
final String className = ByteBuddyProxyHelper.getClassNameWithSuffix( clazz, OPTIMIZER_PROXY_NAMING_SUFFIX )
+ encodeName( propertyNames, getters, setters );
final Class<?> bulkAccessor;
if ( className.getBytes( StandardCharsets.UTF_8 ).length >= 0x10000 ) {
// The JVM has a 64K byte limit on class name length, so fallback to random name if encoding exceeds that
Expand Down Expand Up @@ -305,16 +306,25 @@ private Class<?> determineAccessOptimizerSuperClass(Class<?> clazz, String[] pro
for ( int i = 0; i < getters.length; i++ ) {
final Member getter = getters[i];
final Member setter = setters[i];
boolean found = false;
if ( getter.getDeclaringClass() == foreignPackageClassInfo.clazz && !Modifier.isPublic( getter.getModifiers() ) ) {
foreignPackageClassInfo.getters.add( getter );
found = true;
boolean addPropertyname = false;
if ( getter.getDeclaringClass() == foreignPackageClassInfo.clazz ) {
if( !Modifier.isPublic( getter.getModifiers())) {
foreignPackageClassInfo.getters.add( getter );
}
else {
addPropertyname = true;
}
}
if ( setter.getDeclaringClass() == foreignPackageClassInfo.clazz && !Modifier.isPublic( setter.getModifiers() ) ) {
foreignPackageClassInfo.setters.add( setter );
found = true;
if ( setter.getDeclaringClass() == foreignPackageClassInfo.clazz ) {
if(!Modifier.isPublic( setter.getModifiers() )) {
foreignPackageClassInfo.setters.add( setter );
}
else {
addPropertyname = true;
}

}
if ( found ) {
if ( addPropertyname ) {
foreignPackageClassInfo.propertyNames.add( propertyNames[i] );
}
}
Expand All @@ -328,7 +338,7 @@ private Class<?> determineAccessOptimizerSuperClass(Class<?> clazz, String[] pro
final ForeignPackageClassInfo foreignPackageClassInfo = foreignPackageClassInfos.get( i );
final Class<?> newSuperClass = superClass;

final String className = foreignPackageClassInfo.clazz.getName() + "$" + OPTIMIZER_PROXY_NAMING_SUFFIX + encodeName( foreignPackageClassInfo.propertyNames, foreignPackageClassInfo.getters, foreignPackageClassInfo.setters );
final String className = ByteBuddyProxyHelper.getClassNameWithSuffix( foreignPackageClassInfo.clazz, OPTIMIZER_PROXY_NAMING_SUFFIX ) + encodeName( foreignPackageClassInfo.propertyNames, foreignPackageClassInfo.getters, foreignPackageClassInfo.setters );
superClass = byteBuddyState.load(
foreignPackageClassInfo.clazz,
className,
Expand All @@ -351,7 +361,7 @@ else if ( getter instanceof Method method ) {
TypeDescription.Generic.OfNonGenericType.ForLoadedType.of(
getterType
),
Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
)
.withParameter( foreignPackageClassInfo.clazz )
.intercept(
Expand All @@ -377,7 +387,7 @@ else if ( setter instanceof Method method ) {
builder = builder.defineMethod(
"set_" + setter.getName(),
TypeDescription.Generic.VOID,
Opcodes.ACC_PROTECTED | Opcodes.ACC_STATIC
Opcodes.ACC_PUBLIC | Opcodes.ACC_STATIC
)
.withParameter( foreignPackageClassInfo.clazz )
.withParameter( setterType )
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@

import java.io.Serializable;
import java.lang.reflect.Method;
import java.net.URL;
import java.util.Collection;
import java.util.Collections;
import java.util.HashSet;
Expand Down Expand Up @@ -53,7 +54,7 @@ public Class buildProxy(
}
Collections.addAll( key, interfaces );

final String proxyClassName = persistentClass.getTypeName() + "$" + PROXY_NAMING_SUFFIX;
final String proxyClassName = getClassNameWithSuffix( persistentClass, persistentClass.getTypeName(), PROXY_NAMING_SUFFIX );
return byteBuddyState.loadProxy( persistentClass, proxyClassName,
proxyBuilder( TypeDescription.ForLoadedType.of( persistentClass ), new TypeList.Generic.ForLoadedTypes( interfaces ) ) );
}
Expand Down Expand Up @@ -185,4 +186,25 @@ private static Method resolveIdSetterMethod(SerializableProxy serializableProxy)
);
}
}

private static String getClassNameWithSuffix(Class<?> clazz, String name, String suffix) {
return getClassNameWithCodeSourceLocationHashCode(clazz, name) + "$" + suffix;
}

public static String getClassNameWithSuffix(Class<?> clazz, String suffix) {
return getClassNameWithCodeSourceLocationHashCode(clazz) + "$" + suffix;
}

private static String getClassNameWithCodeSourceLocationHashCode(Class<?> clazz) {
return getClassNameWithCodeSourceLocationHashCode( clazz, clazz.getName() );
}

private static String getClassNameWithCodeSourceLocationHashCode(Class<?> clazz, String className) {
final java.security.CodeSource codeSource = clazz.getProtectionDomain().getCodeSource();
if ( codeSource == null ) {
return className;
}
final URL url = codeSource.getLocation();
return url == null ? className : className + url.toString().hashCode();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;
import jakarta.persistence.Inheritance;
import jakarta.persistence.InheritanceType;
import org.hibernate.orm.test.bytecode.enhancement.optimizer.parent.Ancestor;

@Entity(name = "AncestorEntity")
@Inheritance(strategy = InheritanceType.JOINED)
public class AncestorEntity extends Ancestor {

private Long id;

private String field;

public Long getId() {
return id;
}

public void setId(Long id) {
this.id = id;
}

public String getField() {
return field;
}

public void setField(String field) {
this.field = field;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;

@Entity(name = "ChildEntity3")
public class ChildEntity3 extends AncestorEntity {
private String childField;

public String getChildField() {
return childField;
}

public void setChieldField(String childField) {
this.childField = childField;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;

@Entity(name = "ChildEntity4")
public class ChildEntity4 extends AncestorEntity {
private String childField;

public String getChildField() {
return childField;
}

public void setChieldField(String childField) {
this.childField = childField;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;

@Entity(name = "ChildEntity5")
public class ChildEntity5 extends AncestorEntity {
private String childField;

public String getChildField() {
return childField;
}

public void setChieldField(String childField) {
this.childField = childField;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;

@Entity(name = "ChildEntity6")
public class ChildEntity6 extends AncestorEntity {
private String childField;

public String getChildField() {
return childField;
}

public void setChieldField(String childField) {
this.childField = childField;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;

@Entity(name = "ChildEntity7")
public class ChildEntity7 extends AncestorEntity {
private String childField;

public String getChildField() {
return childField;
}

public void setChildField(String childField) {
this.childField = childField;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;

@Entity(name = "ChildEntity8")
public class ChildEntity8 extends AncestorEntity {
private String childField;

public String getChildField() {
return childField;
}

public void setChildField(String childField) {
this.childField = childField;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
/*
* SPDX-License-Identifier: Apache-2.0
* Copyright Red Hat Inc. and Hibernate Authors
*/
package org.hibernate.orm.test.bytecode.enhancement.optimizer;

import jakarta.persistence.Entity;

@Entity(name = "ChildEntity9")
public class ChildEntity9 extends AncestorEntity {
private String childField;

public String getChildField() {
return childField;
}

public void setChildField(String childField) {
this.childField = childField;
}
}
Loading
Loading