Skip to content

Commit 4309cff

Browse files
committed
HHH-18194 - Remove @Proxy
1 parent 53bca24 commit 4309cff

File tree

38 files changed

+132
-1248
lines changed

38 files changed

+132
-1248
lines changed

documentation/src/main/asciidoc/userguide/chapters/domain/entity.adoc

Lines changed: 0 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -453,50 +453,6 @@ when executing an HQL or JPQL which selects from the `AccountSummary` entity,
453453
Hibernate will trigger a Persistence Context flush if there are pending `Account`, `Client` or `AccountTransaction` entity state transitions.
454454
====
455455

456-
[[entity-proxy]]
457-
==== Define a custom entity proxy
458-
459-
By default, when it needs to use a proxy instead of the actual POJO, Hibernate is going to use a Bytecode manipulation library like
460-
https://bytebuddy.net/[Byte Buddy].
461-
462-
However, if the entity class is final, a proxy will not be created; you will get a POJO even when you only need a proxy reference.
463-
In this case, you could proxy an interface that this particular entity implements, as illustrated by the following example.
464-
465-
NOTE: Supplying a custom proxy class has been allowed historically, but has never seen much use. Also, setting the `lazy` property to `false`, effectively disallowing proxy creation for an entity type, can easily lead to performance degradation due to the N + 1 query issue. As of 6.2 `@Proxy` has been formally deprecated.
466-
467-
See the <<concrete-proxy,@ConcreteProxy>> paragraph if you wish to resolve the concrete type of proxies for the purpose of `instanceof` checks and typecasts.
468-
469-
[[entity-proxy-interface-mapping]]
470-
.Final entity class implementing the `Identifiable` interface
471-
====
472-
[source,java]
473-
----
474-
include::{example-dir-proxy}/ProxyInterfaceTest.java[tag=entity-proxy-interface-mapping,indent=0]
475-
----
476-
====
477-
478-
The https://docs.jboss.org/hibernate/orm/{majorMinorVersion}/javadocs/org/hibernate/annotations/Proxy.html[`@Proxy`]
479-
annotation is used to specify a custom proxy implementation for the current annotated entity.
480-
481-
When loading the `Book` entity proxy, Hibernate is going to proxy the `Identifiable` interface instead as illustrated by the following example:
482-
483-
[[entity-proxy-persist-mapping]]
484-
.Proxying the final entity class implementing the `Identifiable` interface
485-
====
486-
[source,java]
487-
----
488-
include::{example-dir-proxy}/ProxyInterfaceTest.java[tag=entity-proxy-persist-mapping,indent=0]
489-
----
490-
491-
[source,sql]
492-
----
493-
include::{extrasdir}/entity/entity-proxy-persist-mapping.sql[]
494-
----
495-
====
496-
497-
As you can see in the associated SQL snippet, Hibernate issues no SQL SELECT query since the proxy can be
498-
constructed without needing to fetch the actual entity POJO.
499-
500456
[[concrete-proxy]]
501457
==== Create proxies that resolve their inheritance subtype
502458

hibernate-core/src/main/java/org/hibernate/annotations/Proxy.java

Lines changed: 0 additions & 35 deletions
This file was deleted.

hibernate-core/src/main/java/org/hibernate/boot/model/internal/EntityBinder.java

Lines changed: 3 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,6 @@
3737
import org.hibernate.annotations.OnDelete;
3838
import org.hibernate.annotations.OptimisticLockType;
3939
import org.hibernate.annotations.OptimisticLocking;
40-
import org.hibernate.annotations.Proxy;
4140
import org.hibernate.annotations.QueryCacheLayout;
4241
import org.hibernate.annotations.RowId;
4342
import org.hibernate.annotations.SQLDelete;
@@ -1590,27 +1589,9 @@ else if ( "integer".equals( discriminator.getType().getName() ) ) {
15901589
}
15911590

15921591
public void bindProxy() {
1593-
final Proxy proxy = annotatedClass.getAnnotationUsage( Proxy.class, getSourceModelContext() );
1594-
if ( proxy != null ) {
1595-
lazy = proxy.lazy();
1596-
proxyClass = lazy ? resolveProxyClass( proxy, annotatedClass, getSourceModelContext() ) : null;
1597-
}
1598-
else {
1599-
//needed to allow association lazy loading.
1600-
lazy = true;
1601-
proxyClass = annotatedClass;
1602-
}
1603-
}
1604-
1605-
private static ClassDetails resolveProxyClass(
1606-
Proxy proxy,
1607-
ClassDetails annotatedClass,
1608-
SourceModelBuildingContext sourceModelContext) {
1609-
final Class<?> explicitProxyClass = proxy.proxyClass();
1610-
if ( explicitProxyClass == void.class ) {
1611-
return annotatedClass;
1612-
}
1613-
return sourceModelContext.getClassDetailsRegistry().resolveClassDetails( explicitProxyClass.getName() );
1592+
//needed to allow association lazy loading.
1593+
lazy = true;
1594+
proxyClass = annotatedClass;
16141595
}
16151596

16161597
public void bindConcreteProxy() {

hibernate-core/src/main/java/org/hibernate/boot/models/HibernateAnnotations.java

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -488,10 +488,6 @@ public interface HibernateAnnotations {
488488
PartitionKey.class,
489489
PartitionKeyAnnotation.class
490490
);
491-
OrmAnnotationDescriptor<Proxy,ProxyAnnotation> PROXY = new OrmAnnotationDescriptor<>(
492-
Proxy.class,
493-
ProxyAnnotation.class
494-
);
495491
OrmAnnotationDescriptor<PropertyRef,PropertyRefAnnotation> PROPERTY_REF = new OrmAnnotationDescriptor<>(
496492
PropertyRef.class,
497493
PropertyRefAnnotation.class

hibernate-core/src/main/java/org/hibernate/boot/models/annotations/internal/ProxyAnnotation.java

Lines changed: 0 additions & 74 deletions
This file was deleted.

hibernate-core/src/main/java/org/hibernate/boot/models/categorize/internal/EntityTypeMetadataImpl.java

Lines changed: 6 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616
import org.hibernate.annotations.DynamicInsert;
1717
import org.hibernate.annotations.DynamicUpdate;
1818
import org.hibernate.annotations.Immutable;
19-
import org.hibernate.annotations.Proxy;
2019
import org.hibernate.annotations.ResultCheckStyle;
2120
import org.hibernate.annotations.SQLDelete;
2221
import org.hibernate.annotations.SQLInsert;
@@ -40,7 +39,6 @@
4039
import jakarta.persistence.DiscriminatorValue;
4140
import jakarta.persistence.Entity;
4241

43-
import static org.hibernate.boot.models.categorize.internal.CategorizationHelper.toClassDetails;
4442
import static org.hibernate.internal.util.StringHelper.EMPTY_STRINGS;
4543
import static org.hibernate.internal.util.StringHelper.isNotEmpty;
4644
import static org.hibernate.internal.util.StringHelper.unqualify;
@@ -106,29 +104,9 @@ public EntityTypeMetadataImpl(
106104
this.customUpdateMap = extractCustomSql( classDetails, SQLUpdate.class );
107105
this.customDeleteMap = extractCustomSql( classDetails, SQLDelete.class );
108106

109-
//noinspection deprecation
110-
final Proxy proxyAnnotation = classDetails.getDirectAnnotationUsage( Proxy.class );
111-
if ( proxyAnnotation != null ) {
112-
this.isLazy = proxyAnnotation.lazy();
113-
114-
if ( this.isLazy ) {
115-
final ClassDetails proxyClassDetails = toClassDetails( proxyAnnotation.proxyClass(), modelContext.getClassDetailsRegistry() );
116-
if ( proxyClassDetails != null ) {
117-
this.proxy = proxyClassDetails.getName();
118-
}
119-
else {
120-
this.proxy = null;
121-
}
122-
}
123-
else {
124-
this.proxy = null;
125-
}
126-
}
127-
else {
128-
// defaults are that it is lazy and that the class itself is the proxy class
129-
this.isLazy = true;
130-
this.proxy = getEntityName();
131-
}
107+
// defaults are that it is lazy and that the class itself is the proxy class
108+
this.isLazy = true;
109+
this.proxy = getEntityName();
132110

133111
final DiscriminatorValue discriminatorValueAnn = classDetails.getDirectAnnotationUsage( DiscriminatorValue.class );
134112
if ( discriminatorValueAnn != null ) {
@@ -175,29 +153,9 @@ public EntityTypeMetadataImpl(
175153
this.customUpdateMap = extractCustomSql( classDetails, SQLUpdate.class );
176154
this.customDeleteMap = extractCustomSql( classDetails, SQLDelete.class );
177155

178-
//noinspection deprecation
179-
final Proxy proxyAnnotation = classDetails.getDirectAnnotationUsage( Proxy.class );
180-
if ( proxyAnnotation != null ) {
181-
this.isLazy = proxyAnnotation.lazy();
182-
183-
if ( this.isLazy ) {
184-
final ClassDetails proxyClassDetails = toClassDetails( proxyAnnotation.proxyClass(), modelContext.getClassDetailsRegistry() );
185-
if ( proxyClassDetails != null ) {
186-
this.proxy = proxyClassDetails.getName();
187-
}
188-
else {
189-
this.proxy = null;
190-
}
191-
}
192-
else {
193-
this.proxy = null;
194-
}
195-
}
196-
else {
197-
// defaults are that it is lazy and that the class itself is the proxy class
198-
this.isLazy = true;
199-
this.proxy = getEntityName();
200-
}
156+
// defaults are that it is lazy and that the class itself is the proxy class
157+
this.isLazy = true;
158+
this.proxy = getEntityName();
201159

202160
final DiscriminatorValue discriminatorValueAnn = classDetails.getDirectAnnotationUsage( DiscriminatorValue.class );
203161
if ( discriminatorValueAnn != null ) {

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/entity/BasicHibernateAnnotationsTest.java

Lines changed: 18 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -228,27 +228,24 @@ public void testType() throws Exception {
228228
}
229229

230230
@Test
231-
public void testNonLazy() throws Exception {
232-
Session s;
233-
Transaction tx;
234-
s = openSession();
235-
tx = s.beginTransaction();
236-
Forest f = new Forest();
237-
Tree t = new Tree();
238-
t.setName( "Basic one" );
239-
s.persist( f );
240-
s.persist( t );
241-
tx.commit();
242-
s.close();
243-
244-
s = openSession();
245-
tx = s.beginTransaction();
246-
f = (Forest) s.load( Forest.class, f.getId() );
247-
t = (Tree) s.load( Tree.class, t.getId() );
248-
assertFalse( "Default should be lazy", Hibernate.isInitialized( f ) );
249-
assertTrue( "Tree is not lazy", Hibernate.isInitialized( t ) );
250-
tx.commit();
251-
s.close();
231+
public void testLoading() throws Exception {
232+
final Forest created = fromTransaction( (session) -> {
233+
Forest f = new Forest();
234+
session.persist( f );
235+
return f;
236+
} );
237+
238+
// getReference
239+
inTransaction( (session) -> {
240+
final Forest reference = session.getReference( Forest.class, created.getId() );
241+
assertFalse( Hibernate.isInitialized( reference ) );
242+
} );
243+
244+
// find
245+
inTransaction( (session) -> {
246+
final Forest reference = session.find( Forest.class, created.getId() );
247+
assertTrue( Hibernate.isInitialized( reference ) );
248+
} );
252249
}
253250

254251
@Test

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/entity/Tree.java

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,19 +7,15 @@
77

88
//$Id$
99
package org.hibernate.orm.test.annotations.entity;
10+
1011
import jakarta.persistence.Entity;
1112
import jakarta.persistence.GeneratedValue;
1213
import jakarta.persistence.Id;
1314

14-
import org.hibernate.annotations.Proxy;
15-
1615
/**
17-
* Non lazy entity
18-
*
1916
* @author Emmanuel Bernard
2017
*/
2118
@Entity
22-
@Proxy(lazy = false)
2319
public class Tree {
2420
private Integer id;
2521
private String name;

hibernate-core/src/test/java/org/hibernate/orm/test/annotations/idmanytoone/BasketItems.java

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,12 @@
77

88
//$
99
package org.hibernate.orm.test.annotations.idmanytoone;
10+
1011
import java.io.Serializable;
11-
import jakarta.persistence.Basic;
12+
1213
import jakarta.persistence.CascadeType;
1314
import jakarta.persistence.Column;
1415
import jakarta.persistence.Entity;
15-
import jakarta.persistence.FetchType;
1616
import jakarta.persistence.Id;
1717
import jakarta.persistence.IdClass;
1818
import jakarta.persistence.JoinColumn;
@@ -21,7 +21,6 @@
2121

2222
@Entity
2323
@Table(name="BasketItems")
24-
@org.hibernate.annotations.Proxy(lazy=false)
2524
@IdClass(BasketItemsPK.class)
2625
public class BasketItems implements Serializable {
2726

0 commit comments

Comments
 (0)