I am using JBoss 4.0.5 with EJB3 RC9 Patch 1. I tried upgrading to hibernate core 3.2.3, annotations 3.3.0 and entity-manager 3.3.1 and it broke my code.
It was working fine with core 3.2.0, annotation 3.2.1 and entity-manager 3.2.1, but broke on versions after these.
I think there is a bug in BasicPropertyAccessor being passed a wrong target (around line 145). Instead of being passed an instance of my primary key (for which the reflection method was created), it was passed an instance of org.hibernate.property.BackrefPropertyAccessor$1.
I created a greatly simplified test case that can duplicate this problem (code to follow).
I have a class Foo, with an embedded FooPK, containing a collection of Bar entities (with embedded BarPK). Bar objects contains a FooPK as a backref to the containing Foo object. The problem is triggered when I call the entity manager to delete the contained Bar objects.
Here's the error log from the specially instrumented BasicPropertyAccessor:
Code:
2007-04-23 23:09:19,868 ERROR [org.hibernate.property.BasicPropertyAccessor] IllegalArgumentException in class: com.lattiss.foo.FooPK, getter method of property: primaryKey, method="public java.lang.String com.lattiss.foo.FooPK.getPrimaryKey()", target.class=org.hibernate.property.BackrefPropertyAccessor$1
Notice the reflection method is for FooPK, but the invoke() was passed a BackrefPropertyAccessor$1.
Here's the JBoss stack trace:
Code:
javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.lattiss.foo.FooPK.primaryKey" type="javax.ejb.EJBException">javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.lattiss.foo.FooPK.primaryKey
at org.jboss.ejb3.tx.Ejb3TxPolicy.handleExceptionInOurTx(Ejb3TxPolicy.java:69)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:83)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:102)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
Caused by: javax.persistence.PersistenceException: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.lattiss.foo.FooPK.primaryKey
at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)
at org.hibernate.ejb.AbstractEntityManagerImpl.remove(AbstractEntityManagerImpl.java:252)
at org.jboss.ejb3.entity.TransactionScopedEntityManager.remove(TransactionScopedEntityManager.java:187)
at com.lattiss.foo.FooControllerBean.remove(FooControllerBean.java:66)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:102)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
at org.jboss.remoting.RemoteClientInvoker.invoke(RemoteClientInvoker.java:190)
at org.jboss.remoting.Client.invoke(Client.java:525)
at org.jboss.remoting.Client.invoke(Client.java:488)
at org.jboss.aspects.remoting.InvokeRemoteInterceptor.invoke(InvokeRemoteInterceptor.java:55)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.ClientTxPropagationInterceptor.invoke(ClientTxPropagationInterceptor.java:61)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.SecurityClientInterceptor.invoke(SecurityClientInterceptor.java:53)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.remoting.IsLocalInterceptor.invoke(IsLocalInterceptor.java:77)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessRemoteProxy.invoke(StatelessRemoteProxy.java:102)
at $Proxy5.remove(Unknown Source)
at com.lattiss.foo.FooTest.testX(FooTest.java:36)
Caused by: org.hibernate.PropertyAccessException: IllegalArgumentException occurred calling getter of com.lattiss.foo.FooPK.primaryKey
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:173)
at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValue(AbstractComponentTuplizer.java:64)
at org.hibernate.tuple.component.AbstractComponentTuplizer.getPropertyValues(AbstractComponentTuplizer.java:70)
at org.hibernate.tuple.component.PojoComponentTuplizer.getPropertyValues(PojoComponentTuplizer.java:83)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:353)
at org.hibernate.type.ComponentType.getPropertyValues(ComponentType.java:348)
at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:77)
at org.hibernate.engine.ForeignKeys$Nullifier.nullifyTransientReferences(ForeignKeys.java:47)
at org.hibernate.event.def.DefaultDeleteEventListener.deleteEntity(DefaultDeleteEventListener.java:248)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:141)
at org.hibernate.event.def.DefaultDeleteEventListener.onDelete(DefaultDeleteEventListener.java:52)
at org.hibernate.impl.SessionImpl.fireDelete(SessionImpl.java:766)
at org.hibernate.impl.SessionImpl.delete(SessionImpl.java:744)
at org.hibernate.ejb.AbstractEntityManagerImpl.remove(AbstractEntityManagerImpl.java:246)
at org.jboss.ejb3.entity.TransactionScopedEntityManager.remove(TransactionScopedEntityManager.java:187)
at com.lattiss.foo.FooControllerBean.remove(FooControllerBean.java:66)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
at org.jboss.ejb3.interceptor.EJB3InterceptorsInterceptor.invoke(EJB3InterceptorsInterceptor.java:63)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.entity.TransactionScopedEntityManagerInterceptor.invoke(TransactionScopedEntityManagerInterceptor.java:54)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.AllowedOperationsInterceptor.invoke(AllowedOperationsInterceptor.java:46)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPolicy.invokeInOurTx(TxPolicy.java:79)
at org.jboss.aspects.tx.TxInterceptor$Required.invoke(TxInterceptor.java:191)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.tx.TxPropagationInterceptor.invoke(TxPropagationInterceptor.java:76)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessInstanceInterceptor.invoke(StatelessInstanceInterceptor.java:62)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.aspects.security.AuthenticationInterceptor.invoke(AuthenticationInterceptor.java:77)
at org.jboss.ejb3.security.Ejb3AuthenticationInterceptor.invoke(Ejb3AuthenticationInterceptor.java:102)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.ENCPropagationInterceptor.invoke(ENCPropagationInterceptor.java:47)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.asynchronous.AsynchronousInterceptor.invoke(AsynchronousInterceptor.java:106)
at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:101)
at org.jboss.ejb3.stateless.StatelessContainer.dynamicInvoke(StatelessContainer.java:263)
at org.jboss.aop.Dispatcher.invoke(Dispatcher.java:106)
at org.jboss.aspects.remoting.AOPRemotingInvocationHandler.invoke(AOPRemotingInvocationHandler.java:82)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:828)
at org.jboss.remoting.ServerInvoker.invoke(ServerInvoker.java:681)
at org.jboss.remoting.transport.socket.ServerThread.processInvocation(ServerThread.java:358)
at org.jboss.remoting.transport.socket.ServerThread.dorun(ServerThread.java:412)
at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
Caused by: java.lang.IllegalArgumentException: java.lang.ClassCastException@ad2036
at org.hibernate.property.BasicPropertyAccessor$BasicGetter.get(BasicPropertyAccessor.java:145)
Here's the simplified FooPK class:
Code:
package com.lattiss.foo;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Embeddable;
@Embeddable
public class FooPK implements Serializable
{
public FooPK()
{
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj instanceof FooPK)
return m_pk.equals(((FooPK) obj).m_pk);
return false;
}
@Column(name="OID")
public String getPrimaryKey()
{
return m_pk;
}
@Override
public int hashCode()
{
return m_pk.hashCode();
}
public void setPrimaryKey(String s)
{
m_pk = s;
}
private String m_pk;
private static final long serialVersionUID = 1L;
}
Here's the sample contained class, Bar. It's PK definition is similar to FooPK.
Code:
package com.lattiss.foo;
import java.io.Serializable;
import javax.persistence.*;
@Entity
@Table(name="BAR")
public class Bar implements Serializable
{
public Bar()
{
}
@EmbeddedId
public BarPK getBarPk()
{
return m_barPk;
}
@Column(name="DESCRIPTION")
public String getDescription()
{
return m_description;
}
@Embedded
@AttributeOverride(name="primaryKey", column=@Column(name="FOO_OID", nullable=false, insertable=false, updatable=false))
public FooPK getFooPk()
{
return m_fooPk;
}
public void setBarPk(BarPK barPk)
{
m_barPk = barPk;
}
public void setDescription(String description)
{
m_description = description;
}
public void setFooPk(FooPK fooPk)
{
m_fooPk = fooPk;
}
private BarPK m_barPk;
private String m_description;
private FooPK m_fooPk;
private static final long serialVersionUID = 1L;
}
Here's the containing class, Foo:
Code:
package com.lattiss.foo;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
import javax.persistence.*;
@Entity
@Table(name="FOO")
public class Foo implements Serializable
{
public Foo()
{
}
@OneToMany(cascade={CascadeType.ALL}, fetch=FetchType.LAZY)
@JoinColumn(name="FOO_OID", nullable=false, updatable=false)
public List<Bar> getBars()
{
return m_bars;
}
@Column(name="DESCRIPTION")
public String getDescription()
{
return m_description;
}
@EmbeddedId
public FooPK getFooPk()
{
return m_fooPk;
}
public void setBars(List<Bar> bars)
{
m_bars = bars;
}
public void setDescription(String description)
{
m_description = description;
}
public void setFooPk(FooPK pk)
{
m_fooPk = pk;
}
private FooPK m_fooPk;
private String m_description;
private List<Bar> m_bars = new ArrayList<Bar>();
private static final long serialVersionUID = 1L;
}
The code that trigged the problem:
Code:
@TransactionAttribute(TransactionAttributeType.REQUIRED)
public void remove()
{
FooPK fooPk = new FooPK();
fooPk.setPrimaryKey("1");
Foo foo = m_entityManager.find(Foo.class, fooPk);
List<Bar> bars = foo.getBars();
for (Bar b : bars)
{
m_entityManager.remove(b);
}
}
I would like to know if this can be scheduled for a fix soon.
Thanks,
Haam