HHH-12982 - Generify Hibernate#unproxy

This commit is contained in:
Vlad Mihalcea 2018-09-19 10:26:16 +03:00
parent 340618c9a0
commit 01bf67e4b8
2 changed files with 195 additions and 122 deletions

View File

@ -212,4 +212,16 @@ public static Object unproxy(Object proxy) {
return proxy; return proxy;
} }
} }
/**
* Unproxies a {@link HibernateProxy}. If the proxy is uninitialized, it automatically triggers an initialization.
* In case the supplied object is null or not a proxy, the object will be returned as-is.
*
* @param proxy the {@link HibernateProxy} to be unproxied
* @param entityClass the entity type
* @return the proxy's underlying implementation object, or the supplied object otherwise
*/
public static <T> T unproxy(T proxy, Class<T> entityClass) {
return entityClass.cast( unproxy( proxy ) );
}
} }

View File

@ -6,93 +6,150 @@
*/ */
package org.hibernate.test.proxy; package org.hibernate.test.proxy;
import java.util.Objects;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import org.hibernate.Hibernate; import org.hibernate.Hibernate;
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase; import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
import org.jboss.logging.Logger;
import org.junit.Test; import org.junit.Test;
import javax.persistence.*;
import java.util.Objects;
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA; import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
import static org.junit.Assert.*; import static org.junit.Assert.assertEquals;
import static org.junit.Assert.assertFalse;
import static org.junit.Assert.assertNull;
import static org.junit.Assert.assertSame;
import static org.junit.Assert.assertTrue;
public class HibernateUnproxyTest extends BaseEntityManagerFunctionalTestCase { public class HibernateUnproxyTest extends BaseEntityManagerFunctionalTestCase {
@Override @Override
protected Class<?>[] getAnnotatedClasses() { protected Class<?>[] getAnnotatedClasses() {
return new Class<?>[]{Parent.class, Child.class}; return new Class<?>[] { Parent.class, Child.class };
} }
@Test @Test
public void testInitializedProxyCanBeUnproxied() { public void testInitializedProxyCanBeUnproxied() {
Parent p = new Parent(); Parent p = new Parent();
Child c = new Child(); Child c = new Child();
p.setChild(c); p.setChild( c );
doInJPA(this::entityManagerFactory, (entityManager -> {
entityManager.persist(p); doInJPA( this::entityManagerFactory, ( entityManager -> {
})); entityManager.persist( p );
doInJPA(this::entityManagerFactory, (entityManager -> { } ) );
Parent parent = entityManager.find(Parent.class, p.getId());
doInJPA( this::entityManagerFactory, ( entityManager -> {
Parent parent = entityManager.find( Parent.class, p.getId() );
Child child = parent.getChild(); Child child = parent.getChild();
assertFalse(Hibernate.isInitialized(child));
Hibernate.initialize(child); assertFalse( Hibernate.isInitialized( child ) );
Child unproxiedChild = (Child) Hibernate.unproxy(child); Hibernate.initialize( child );
assertEquals(Child.class, unproxiedChild.getClass());
})); Child unproxiedChild = (Child) Hibernate.unproxy( child );
assertEquals( Child.class, unproxiedChild.getClass() );
} ) );
doInJPA( this::entityManagerFactory, ( entityManager -> {
Parent parent = entityManager.find( Parent.class, p.getId() );
Child child = parent.getChild();
assertFalse( Hibernate.isInitialized( child ) );
Hibernate.initialize( child );
Child unproxiedChild = Hibernate.unproxy( child, Child.class );
assertEquals( Child.class, unproxiedChild.getClass() );
} ) );
} }
@Test @Test
public void testNotInitializedProxyCanBeUnproxiedWithInitialization() { public void testNotInitializedProxyCanBeUnproxiedWithInitialization() {
Parent p = new Parent(); Parent p = new Parent();
Child c = new Child(); Child c = new Child();
p.setChild(c); p.setChild( c );
doInJPA(this::entityManagerFactory, (entityManager -> {
entityManager.persist(p); doInJPA( this::entityManagerFactory, ( entityManager -> {
})); entityManager.persist( p );
doInJPA(this::entityManagerFactory, (entityManager -> { } ) );
Parent parent = entityManager.find(Parent.class, p.getId());
doInJPA( this::entityManagerFactory, ( entityManager -> {
Parent parent = entityManager.find( Parent.class, p.getId() );
Child child = parent.getChild(); Child child = parent.getChild();
assertFalse(Hibernate.isInitialized(child));
Child unproxiedChild = (Child) Hibernate.unproxy(child); assertFalse( Hibernate.isInitialized( child ) );
assertTrue(Hibernate.isInitialized(child));
assertEquals(Child.class, unproxiedChild.getClass()); Child unproxiedChild = (Child) Hibernate.unproxy( child );
}));
assertTrue( Hibernate.isInitialized( child ) );
assertEquals( Child.class, unproxiedChild.getClass() );
} ) );
doInJPA( this::entityManagerFactory, ( entityManager -> {
Parent parent = entityManager.find( Parent.class, p.getId() );
Child child = parent.getChild();
assertFalse( Hibernate.isInitialized( child ) );
Child unproxiedChild = Hibernate.unproxy( child, Child.class );
assertTrue( Hibernate.isInitialized( child ) );
assertEquals( Child.class, unproxiedChild.getClass() );
} ) );
} }
@Test @Test
public void testNotHibernateProxyShouldThrowException() { public void testNotHibernateProxyShouldThrowException() {
Parent p = new Parent(); Parent p = new Parent();
Child c = new Child(); Child c = new Child();
p.setChild(c); p.setChild( c );
doInJPA(this::entityManagerFactory, (entityManager -> {
entityManager.persist(p); doInJPA( this::entityManagerFactory, ( entityManager -> {
})); entityManager.persist( p );
doInJPA(this::entityManagerFactory, (entityManager -> { } ) );
Parent parent = entityManager.find(Parent.class, p.getId());
assertSame(parent, Hibernate.unproxy(parent)); doInJPA( this::entityManagerFactory, ( entityManager -> {
})); Parent parent = entityManager.find( Parent.class, p.getId() );
assertSame( parent, Hibernate.unproxy( parent ) );
} ) );
doInJPA( this::entityManagerFactory, ( entityManager -> {
Parent parent = entityManager.find( Parent.class, p.getId() );
assertSame( parent, Hibernate.unproxy( parent, Parent.class ) );
} ) );
} }
@Test @Test
public void testNullUnproxyReturnsNull() { public void testNullUnproxyReturnsNull() {
assertNull(Hibernate.unproxy(null)); assertNull( Hibernate.unproxy( null ) );
assertNull( Hibernate.unproxy( null, Parent.class ) );
} }
@Test @Test
public void testProxyEquality() { public void testProxyEquality() {
Parent parent = doInJPA(this::entityManagerFactory, (entityManager -> { Parent parent = doInJPA( this::entityManagerFactory, ( entityManager -> {
Parent p = new Parent(); Parent p = new Parent();
p.name = "John Doe"; p.name = "John Doe";
entityManager.persist(p); entityManager.persist( p );
return p; return p;
})); } ) );
doInJPA(this::entityManagerFactory, (entityManager -> {
Parent p = entityManager.getReference(Parent.class, parent.getId()); doInJPA( this::entityManagerFactory, ( entityManager -> {
assertFalse(parent.equals(p)); Parent p = entityManager.getReference( Parent.class, parent.getId() );
assertTrue(parent.equals(Hibernate.unproxy(p))); assertFalse( parent.equals( p ) );
})); assertTrue( parent.equals( Hibernate.unproxy( p ) ) );
} ) );
doInJPA( this::entityManagerFactory, ( entityManager -> {
Parent p = entityManager.getReference( Parent.class, parent.getId() );
assertFalse( parent.equals( p ) );
assertTrue( parent.equals( Hibernate.unproxy( p, Parent.class ) ) );
} ) );
} }
@Entity(name = "Parent") @Entity(name = "Parent")
@ -112,7 +169,7 @@ public Integer getId() {
public void setChild(Child child) { public void setChild(Child child) {
this.child = child; this.child = child;
child.setParent(this); child.setParent( this );
} }
public Child getChild() { public Child getChild() {
@ -121,15 +178,19 @@ public Child getChild() {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (this == o) return true; if ( this == o ) {
if (o == null || getClass() != o.getClass()) return false; return true;
}
if ( o == null || getClass() != o.getClass() ) {
return false;
}
Parent parent = (Parent) o; Parent parent = (Parent) o;
return Objects.equals(name, parent.name); return Objects.equals( name, parent.name );
} }
@Override @Override
public int hashCode() { public int hashCode() {
return Objects.hash(name); return Objects.hash( name );
} }
} }