Skip to content

Commit 4ac2054

Browse files
fgsofisyrodiere
authored andcommitted
HHH-15522 Implement a LazyInitializable interface that PersistentCollection and Envers collections extend or implement. Improve related tests.
1 parent c3f1762 commit 4ac2054

File tree

9 files changed

+109
-54
lines changed

9 files changed

+109
-54
lines changed

hibernate-core/src/main/java/org/hibernate/Hibernate.java

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,6 +34,7 @@
3434
import org.hibernate.persister.entity.EntityPersister;
3535
import org.hibernate.proxy.HibernateProxy;
3636
import org.hibernate.proxy.LazyInitializer;
37+
import org.hibernate.collection.spi.LazyInitializable;
3738

3839
/**
3940
* Various utility functions for working with proxies and lazy collection references.
@@ -85,8 +86,8 @@ public static void initialize(Object proxy) throws HibernateException {
8586
if ( proxy instanceof HibernateProxy ) {
8687
( (HibernateProxy) proxy ).getHibernateLazyInitializer().initialize();
8788
}
88-
else if ( proxy instanceof PersistentCollection ) {
89-
( (PersistentCollection<?>) proxy ).forceInitialization();
89+
else if ( proxy instanceof LazyInitializable ) {
90+
( (LazyInitializable) proxy ).forceInitialization();
9091
}
9192
else if ( proxy instanceof PersistentAttributeInterceptable ) {
9293
final PersistentAttributeInterceptable interceptable = (PersistentAttributeInterceptable) proxy;
@@ -111,8 +112,8 @@ else if ( proxy instanceof PersistentAttributeInterceptable ) {
111112
final PersistentAttributeInterceptor interceptor = ( (PersistentAttributeInterceptable) proxy ).$$_hibernate_getInterceptor();
112113
return !(interceptor instanceof EnhancementAsProxyLazinessInterceptor);
113114
}
114-
else if ( proxy instanceof PersistentCollection ) {
115-
return ( (PersistentCollection<?>) proxy ).wasInitialized();
115+
else if ( proxy instanceof LazyInitializable ) {
116+
return ( (LazyInitializable) proxy ).wasInitialized();
116117
}
117118
else {
118119
return true;
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
/*
2+
* Hibernate, Relational Persistence for Idiomatic Java
3+
*
4+
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
5+
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
6+
*/
7+
package org.hibernate.collection.spi;
8+
9+
import org.hibernate.Incubating;
10+
11+
/**
12+
* Hibernate "wraps" a java collection in an instance of PersistentCollection. Envers uses custom collection
13+
* wrappers (ListProxy, SetProxy, etc). All of them need to extend LazyInitializable, so the
14+
* Hibernate.isInitialized method can check if the collection is initialized or not.
15+
*
16+
* @author Fabricio Gregorio
17+
*/
18+
@Incubating
19+
public interface LazyInitializable {
20+
21+
/**
22+
* Is this instance initialized?
23+
*
24+
* @return Was this collection initialized? Or is its data still not (fully) loaded?
25+
*/
26+
boolean wasInitialized();
27+
28+
/**
29+
* To be called internally by the session, forcing immediate initialization.
30+
*/
31+
void forceInitialization();
32+
33+
}

hibernate-core/src/main/java/org/hibernate/collection/spi/PersistentCollection.java

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
* @author Gavin King
4949
*/
5050
@Incubating
51-
public interface PersistentCollection<E> {
51+
public interface PersistentCollection<E> extends LazyInitializable {
5252
/**
5353
* Get the owning entity. Note that the owner is only
5454
* set during the flush cycle, and when a new collection
@@ -211,11 +211,6 @@ public interface PersistentCollection<E> {
211211
*/
212212
Serializable getSnapshot(CollectionPersister persister);
213213

214-
/**
215-
* To be called internally by the session, forcing immediate initialization.
216-
*/
217-
void forceInitialization();
218-
219214
/**
220215
* Does the given element/entry exist in the collection?
221216
*
@@ -280,13 +275,6 @@ public interface PersistentCollection<E> {
280275
*/
281276
boolean isInitializing();
282277

283-
/**
284-
* Is this instance initialized?
285-
*
286-
* @return Was this collection initialized? Or is its data still not (fully) loaded?
287-
*/
288-
boolean wasInitialized();
289-
290278
/**
291279
* Called prior to the initialization of this yet-uninitialized collection. Pairs
292280
* with {@link #afterInitialize}

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/CollectionProxy.java

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9,13 +9,15 @@
99
import java.io.Serializable;
1010
import java.util.Collection;
1111
import java.util.Iterator;
12+
import org.hibernate.collection.spi.LazyInitializable;
1213

1314
import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor;
1415

1516
/**
1617
* @author Adam Warski (adam at warski dot org)
1718
*/
18-
public abstract class CollectionProxy<U, T extends Collection<U>> implements Collection<U>, Serializable {
19+
public abstract class CollectionProxy<U, T extends Collection<U>> implements Collection<U>, LazyInitializable, Serializable {
20+
1921
private static final long serialVersionUID = 8698249863871832402L;
2022

2123
private transient Initializor<T> initializor;
@@ -34,6 +36,16 @@ protected void checkInit() {
3436
}
3537
}
3638

39+
@Override
40+
public final boolean wasInitialized() {
41+
return delegate != null;
42+
}
43+
44+
@Override
45+
public final void forceInitialization() {
46+
checkInit();
47+
}
48+
3749
@Override
3850
public int size() {
3951
checkInit();
@@ -118,7 +130,7 @@ public String toString() {
118130
return delegate.toString();
119131
}
120132

121-
@SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
133+
@SuppressWarnings({ "EqualsWhichDoesntCheckParameterClass" })
122134
@Override
123135
public boolean equals(Object obj) {
124136
checkInit();

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/MapProxy.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,13 +10,14 @@
1010
import java.util.Collection;
1111
import java.util.Map;
1212
import java.util.Set;
13-
13+
import org.hibernate.collection.spi.LazyInitializable;
1414
import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor;
1515

1616
/**
1717
* @author Adam Warski (adam at warski dot org)
1818
*/
19-
public class MapProxy<K, V> implements Map<K, V>, Serializable {
19+
public class MapProxy<K, V> implements Map<K, V>, LazyInitializable, Serializable {
20+
2021
private static final long serialVersionUID = 8418037541773074646L;
2122

2223
private transient Initializor<Map<K, V>> initializor;
@@ -35,6 +36,16 @@ private void checkInit() {
3536
}
3637
}
3738

39+
@Override
40+
public final boolean wasInitialized() {
41+
return delegate != null;
42+
}
43+
44+
@Override
45+
public final void forceInitialization() {
46+
checkInit();
47+
}
48+
3849
@Override
3950
public int size() {
4051
checkInit();
@@ -114,7 +125,7 @@ public String toString() {
114125
}
115126

116127
@Override
117-
@SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
128+
@SuppressWarnings({ "EqualsWhichDoesntCheckParameterClass" })
118129
public boolean equals(Object obj) {
119130
checkInit();
120131
return delegate.equals( obj );

hibernate-envers/src/main/java/org/hibernate/envers/internal/entities/mapper/relation/lazy/proxy/SortedMapProxy.java

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,13 +12,14 @@
1212
import java.util.Map;
1313
import java.util.Set;
1414
import java.util.SortedMap;
15-
15+
import org.hibernate.collection.spi.LazyInitializable;
1616
import org.hibernate.envers.internal.entities.mapper.relation.lazy.initializor.Initializor;
1717

1818
/**
1919
* @author Adam Warski (adam at warski dot org)
2020
*/
21-
public class SortedMapProxy<K, V> implements SortedMap<K, V>, Serializable {
21+
public class SortedMapProxy<K, V> implements SortedMap<K, V>, LazyInitializable, Serializable {
22+
2223
private static final long serialVersionUID = 2645817952901452375L;
2324

2425
private transient Initializor<SortedMap<K, V>> initializor;
@@ -37,6 +38,16 @@ private void checkInit() {
3738
}
3839
}
3940

41+
@Override
42+
public final boolean wasInitialized() {
43+
return delegate != null;
44+
}
45+
46+
@Override
47+
public final void forceInitialization() {
48+
checkInit();
49+
}
50+
4051
@Override
4152
public int size() {
4253
checkInit();
@@ -146,7 +157,7 @@ public K lastKey() {
146157
}
147158

148159
@Override
149-
@SuppressWarnings({"EqualsWhichDoesntCheckParameterClass"})
160+
@SuppressWarnings({ "EqualsWhichDoesntCheckParameterClass" })
150161
public boolean equals(Object o) {
151162
checkInit();
152163
return delegate.equals( o );

hibernate-envers/src/test/java/org/hibernate/orm/test/envers/entities/collection/MultipleCollectionEntity.java

Lines changed: 16 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
import java.util.ArrayList;
1010
import java.util.Collections;
1111
import java.util.List;
12+
import java.util.Objects;
13+
1214
import jakarta.persistence.CascadeType;
1315
import jakarta.persistence.Column;
1416
import jakarta.persistence.Entity;
@@ -26,6 +28,7 @@
2628
@Entity
2729
@Audited
2830
public class MultipleCollectionEntity {
31+
2932
@Id
3033
@GeneratedValue(strategy = GenerationType.IDENTITY)
3134
@Column(name = "ID", length = 10)
@@ -65,7 +68,7 @@ public void setText(String text) {
6568
}
6669

6770
public List<MultipleCollectionRefEntity1> getRefEntities1() {
68-
return Collections.unmodifiableList( refEntities1 );
71+
return refEntities1;
6972
}
7073

7174
public void addRefEntity1(MultipleCollectionRefEntity1 refEntity1) {
@@ -77,7 +80,7 @@ public void removeRefEntity1(MultipleCollectionRefEntity1 refEntity1) {
7780
}
7881

7982
public List<MultipleCollectionRefEntity2> getRefEntities2() {
80-
return Collections.unmodifiableList( refEntities2 );
83+
return refEntities2;
8184
}
8285

8386
public void addRefEntity2(MultipleCollectionRefEntity2 refEntity2) {
@@ -110,34 +113,20 @@ public String toString() {
110113
}
111114

112115
@Override
113-
public boolean equals(Object o) {
114-
if ( this == o ) {
115-
return true;
116-
}
117-
if ( !(o instanceof MultipleCollectionEntity) ) {
118-
return false;
119-
}
120-
121-
MultipleCollectionEntity that = (MultipleCollectionEntity) o;
116+
public int hashCode() {
117+
return Objects.hash( id );
118+
}
122119

123-
if ( refEntities1 != null ? !refEntities1.equals( that.refEntities1 ) : that.refEntities1 != null ) {
124-
return false;
125-
}
126-
if ( refEntities2 != null ? !refEntities2.equals( that.refEntities2 ) : that.refEntities2 != null ) {
120+
@Override
121+
public boolean equals(Object obj) {
122+
if ( this == obj )
123+
return true;
124+
if ( obj == null )
127125
return false;
128-
}
129-
if ( text != null ? !text.equals( that.text ) : that.text != null ) {
126+
if ( getClass() != obj.getClass() )
130127
return false;
131-
}
132-
133-
return true;
128+
MultipleCollectionEntity other = (MultipleCollectionEntity) obj;
129+
return Objects.equals( id, other.id );
134130
}
135131

136-
@Override
137-
public int hashCode() {
138-
int result = text != null ? text.hashCode() : 0;
139-
result = 31 * result + (refEntities1 != null ? refEntities1.hashCode() : 0);
140-
result = 31 * result + (refEntities2 != null ? refEntities2.hashCode() : 0);
141-
return result;
142-
}
143132
}

hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/lazy/IsCollectionInitializedBytecodeEnhancementTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ public void initData() {
7777
}
7878

7979
@Test
80+
@SuppressWarnings("unchecked")
8081
public void testIsInitialized() {
8182
EntityManager em = getEntityManager();
8283

@@ -88,6 +89,10 @@ public void testIsInitialized() {
8889
MultipleCollectionEntity ret = res.get( 0 );
8990

9091
assertEquals( Hibernate.isInitialized( ret.getRefEntities1() ), false );
91-
92+
93+
Hibernate.initialize(ret.getRefEntities1());
94+
95+
assertEquals( Hibernate.isInitialized( ret.getRefEntities1() ), true );
96+
9297
}
9398
}

hibernate-envers/src/test/java/org/hibernate/orm/test/envers/integration/lazy/IsCollectionInitializedTest.java

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ public void initData() {
7272
}
7373

7474
@Test
75+
@SuppressWarnings("unchecked")
7576
public void testIsInitialized() {
7677
EntityManager em = getEntityManager();
7778

@@ -81,8 +82,12 @@ public void testIsInitialized() {
8182
.getResultList();
8283

8384
MultipleCollectionEntity ret = res.get( 0 );
84-
85+
8586
assertEquals( Hibernate.isInitialized( ret.getRefEntities1() ), false );
87+
88+
Hibernate.initialize(ret.getRefEntities1());
89+
90+
assertEquals( Hibernate.isInitialized( ret.getRefEntities1() ), true );
8691

8792
}
8893
}

0 commit comments

Comments
 (0)