HHH-12786 Allow to call methods when the interceptor is not set yet
Typically, if the constructor calls instrumented methods, the interceptor is not defined yet and we get a NPE.
This commit is contained in:
parent
297031319d
commit
0fda6be86e
|
@ -26,6 +26,7 @@ public class BasicProxyFactoryImpl implements BasicProxyFactory {
|
||||||
|
|
||||||
private final Class proxyClass;
|
private final Class proxyClass;
|
||||||
|
|
||||||
|
@SuppressWarnings("unchecked")
|
||||||
public BasicProxyFactoryImpl(Class superClass, Class[] interfaces, ByteBuddyState bytebuddy) {
|
public BasicProxyFactoryImpl(Class superClass, Class[] interfaces, ByteBuddyState bytebuddy) {
|
||||||
if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
|
if ( superClass == null && ( interfaces == null || interfaces.length < 1 ) ) {
|
||||||
throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
|
throw new AssertionFailure( "attempting to build proxy without any superclass or interfaces" );
|
||||||
|
@ -39,7 +40,7 @@ public class BasicProxyFactoryImpl implements BasicProxyFactory {
|
||||||
.implement( interfaces == null ? NO_INTERFACES : interfaces )
|
.implement( interfaces == null ? NO_INTERFACES : interfaces )
|
||||||
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )
|
.defineField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME, ProxyConfiguration.Interceptor.class, Visibility.PRIVATE )
|
||||||
.method( ElementMatchers.isVirtual().and( ElementMatchers.not( ElementMatchers.isFinalizer() ) ) )
|
.method( ElementMatchers.isVirtual().and( ElementMatchers.not( ElementMatchers.isFinalizer() ) ) )
|
||||||
.intercept( MethodDelegation.toField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME ) )
|
.intercept( MethodDelegation.to( ProxyConfiguration.InterceptorDispatcher.class ) )
|
||||||
.implement( ProxyConfiguration.class )
|
.implement( ProxyConfiguration.class )
|
||||||
.intercept( FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME ).withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC ) )
|
.intercept( FieldAccessor.ofField( ProxyConfiguration.INTERCEPTOR_FIELD_NAME ).withAssigner( Assigner.DEFAULT, Assigner.Typing.DYNAMIC ) )
|
||||||
.make()
|
.make()
|
||||||
|
|
|
@ -0,0 +1,21 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.component.proxy;
|
||||||
|
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
public class Adult extends Person {
|
||||||
|
|
||||||
|
public Adult() {
|
||||||
|
someInitMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void someInitMethod() {
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,47 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.component.proxy;
|
||||||
|
|
||||||
|
import static org.hibernate.testing.transaction.TransactionUtil.doInJPA;
|
||||||
|
|
||||||
|
import java.util.List;
|
||||||
|
|
||||||
|
import org.hibernate.jpa.test.BaseEntityManagerFunctionalTestCase;
|
||||||
|
import org.hibernate.testing.TestForIssue;
|
||||||
|
import org.junit.Test;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @author Guillaume Smet
|
||||||
|
* @author Oliver Libutzki
|
||||||
|
*/
|
||||||
|
public class ComponentBasicProxyTest extends BaseEntityManagerFunctionalTestCase {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected Class<?>[] getAnnotatedClasses() {
|
||||||
|
return new Class[]{
|
||||||
|
Person.class, Adult.class
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
@Test
|
||||||
|
@TestForIssue(jiraKey = "HHH-12786")
|
||||||
|
public void testBasicProxyingWithProtectedMethodCalledInConstructor() {
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
Adult adult = new Adult();
|
||||||
|
adult.setName( "Arjun Kumar" );
|
||||||
|
entityManager.persist( adult );
|
||||||
|
} );
|
||||||
|
|
||||||
|
doInJPA( this::entityManagerFactory, entityManager -> {
|
||||||
|
List<Adult> adultsCalledArjun = entityManager
|
||||||
|
.createQuery( "SELECT a from Adult a WHERE a.name = :name", Adult.class )
|
||||||
|
.setParameter( "name", "Arjun Kumar" ).getResultList();
|
||||||
|
Adult adult = adultsCalledArjun.iterator().next();
|
||||||
|
entityManager.remove( adult );
|
||||||
|
} );
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,68 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.component.proxy;
|
||||||
|
|
||||||
|
import javax.persistence.Column;
|
||||||
|
import javax.persistence.Entity;
|
||||||
|
import javax.persistence.GeneratedValue;
|
||||||
|
import javax.persistence.GenerationType;
|
||||||
|
import javax.persistence.Id;
|
||||||
|
import javax.persistence.IdClass;
|
||||||
|
import javax.persistence.Table;
|
||||||
|
|
||||||
|
@Entity
|
||||||
|
@Table(name = "person")
|
||||||
|
@IdClass(PersonId.class)
|
||||||
|
public abstract class Person {
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Column(name = "id")
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
@Id
|
||||||
|
@GeneratedValue(strategy = GenerationType.AUTO)
|
||||||
|
@Column(name = "clientId")
|
||||||
|
private int clientId;
|
||||||
|
|
||||||
|
@Column(name = "name")
|
||||||
|
private String name;
|
||||||
|
|
||||||
|
@Column(name = "title")
|
||||||
|
private String title;
|
||||||
|
|
||||||
|
public Person() {
|
||||||
|
someInitMethod();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void someInitMethod() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClientId() {
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getName() {
|
||||||
|
return name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setName(String name) {
|
||||||
|
this.name = name;
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getTitle(String name) {
|
||||||
|
return title;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setTitle(String title) {
|
||||||
|
this.title = title;
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,42 @@
|
||||||
|
/*
|
||||||
|
* Hibernate, Relational Persistence for Idiomatic Java
|
||||||
|
*
|
||||||
|
* License: GNU Lesser General Public License (LGPL), version 2.1 or later.
|
||||||
|
* See the lgpl.txt file in the root directory or <http://www.gnu.org/licenses/lgpl-2.1.html>.
|
||||||
|
*/
|
||||||
|
package org.hibernate.test.component.proxy;
|
||||||
|
|
||||||
|
import java.io.Serializable;
|
||||||
|
|
||||||
|
@SuppressWarnings("all")
|
||||||
|
public class PersonId implements Serializable {
|
||||||
|
|
||||||
|
private int id;
|
||||||
|
|
||||||
|
private int clientId;
|
||||||
|
|
||||||
|
public PersonId() {
|
||||||
|
}
|
||||||
|
|
||||||
|
public PersonId(int aId, int aClientId) {
|
||||||
|
setId( aId );
|
||||||
|
setClientId( aClientId );
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getId() {
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setId(int aId) {
|
||||||
|
this.id = aId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public int getClientId() {
|
||||||
|
|
||||||
|
return clientId;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setClientId(int aClientId) {
|
||||||
|
clientId = aClientId;
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue