Skip to content

Commit 05e0a71

Browse files
committed
Create proxies for abstract entity classes too in Hibernate ORM
1 parent 11f03db commit 05e0a71

File tree

4 files changed

+49
-4
lines changed

4 files changed

+49
-4
lines changed

extensions/hibernate-orm/deployment/src/main/java/io/quarkus/hibernate/orm/deployment/ProxyBuildingHelper.java

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,6 @@ private ByteBuddyProxyHelper getByteBuddyProxyHelper() {
4444
public boolean isProxiable(ClassInfo classInfo) {
4545
return classInfo != null
4646
&& !classInfo.isInterface()
47-
&& !classInfo.isAbstract()
4847
&& !classInfo.isFinal()
4948
&& classInfo.hasNoArgsConstructor();
5049
}

extensions/hibernate-orm/runtime/src/main/java/io/quarkus/hibernate/orm/runtime/customized/QuarkusProxyFactory.java

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,6 @@ public void postInstantiate(String entityName, Class<?> persistentClass, Set<Cla
6969
else if (Modifier.isFinal(persistentClass.getModifiers())) {
7070
reason = "this class is final. Your application might perform better if this class was non-final.";
7171
}
72-
if (Modifier.isAbstract(persistentClass.getModifiers())) {
73-
reason = "this class is abstract. Your application might perform better if this class was non-abstract.";
74-
}
7572
if (reason != null) {
7673
// This is caught and logged as a warning by Hibernate ORM.
7774
throw new HibernateException(String.format(Locale.ROOT,

integration-tests/jpa/src/main/java/io/quarkus/it/jpa/proxy/ProxyTestEndpoint.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,8 @@
1212
import jakarta.ws.rs.Produces;
1313
import jakarta.ws.rs.core.MediaType;
1414

15+
import org.hibernate.proxy.HibernateProxy;
16+
1517
import io.quarkus.narayana.jta.QuarkusTransaction;
1618
import io.quarkus.narayana.jta.runtime.TransactionConfiguration;
1719
import io.quarkus.runtime.StartupEvent;
@@ -78,6 +80,18 @@ public String testBasic() {
7880
return "OK";
7981
}
8082

83+
@GET
84+
@Path("abstract")
85+
@Transactional
86+
public String testAbstract() {
87+
var result = entityManager.getReference(AbstractEntity.class, "1");
88+
expectTrue(result != null);
89+
expectTrue(result instanceof HibernateProxy);
90+
// Make sure we don't get fooled by some kind of "fallback" eager loading
91+
expectFalse(result instanceof ConcreteEntity);
92+
return "OK";
93+
}
94+
8195
/**
8296
* tests for the @Proxy annotation in an inheritance hierarchy
8397
*

integration-tests/jpa/src/test/java/io/quarkus/it/jpa/proxy/ProxyTest.java

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,26 @@
11
package io.quarkus.it.jpa.proxy;
22

3+
import static org.assertj.core.api.Assertions.assertThat;
34
import static org.hamcrest.Matchers.is;
45

56
import org.junit.jupiter.api.Test;
67

8+
import io.quarkus.test.LogCollectingTestResource;
9+
import io.quarkus.test.common.QuarkusTestResource;
10+
import io.quarkus.test.common.ResourceArg;
11+
import io.quarkus.test.junit.DisabledOnIntegrationTest;
712
import io.quarkus.test.junit.QuarkusTest;
813
import io.restassured.RestAssured;
914

1015
@QuarkusTest
16+
@QuarkusTestResource(value = LogCollectingTestResource.class, restrictToAnnotatedClass = true, initArgs = {
17+
@ResourceArg(name = LogCollectingTestResource.LEVEL, value = "WARNING"),
18+
@ResourceArg(name = LogCollectingTestResource.INCLUDE, value = "org\\.hibernate\\..*"),
19+
// Ignore logs about schema management:
20+
// they are unfortunate (https://github.com/quarkusio/quarkus/issues/16204)
21+
// but for now we have to live with them.
22+
@ResourceArg(name = LogCollectingTestResource.EXCLUDE, value = "org\\.hibernate\\.tool\\.schema.*")
23+
})
1124
public class ProxyTest {
1225

1326
@Test
@@ -25,4 +38,26 @@ public void testEnhancedProxies() {
2538
RestAssured.when().get("/jpa-test/proxy/enhanced").then().body(is("OK"));
2639
}
2740

41+
@Test
42+
public void testAbstractClassProxies() {
43+
RestAssured.when().get("/jpa-test/proxy/abstract").then().body(is("OK"));
44+
}
45+
46+
@Test
47+
// When running as integration test, we cannot easily spy on logs.
48+
@DisabledOnIntegrationTest
49+
public void testProxyWarningsOnStartup() {
50+
assertThat(LogCollectingTestResource.current().getRecords())
51+
// There shouldn't be any warning or error
52+
.as("Startup logs (warning or higher)")
53+
.extracting(LogCollectingTestResource::format)
54+
.satisfiesExactlyInAnyOrder(
55+
// Final classes cannot be proxied
56+
m -> assertThat(m).contains(
57+
"Could not create proxy factory", CompanyCustomer.class.getName(),
58+
"this class is final", "Your application might perform better if this class was non-final.")
59+
// Importantly, we don't expect any other warning about proxies!
60+
);
61+
}
62+
2863
}

0 commit comments

Comments
 (0)