EJB3 PersistanceManager confusion
jrosskopf Sep 6, 2006 11:21 AMHello List,
I try to do my first steps with EJB3 and set up a small example persisting a detatched pojo entity (which is generated in a client) through a stateless session bean.
I´ll attach the code of the three components at the end of the message.
When I invoke the the method, that should persist the entity I get the following exception:
Exception in thread "main" javax.ejb.EJBException: javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: com.toolsforjobs.j2ee.test.server.domain.Debtor 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:197) 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:78) 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:225) 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:398) at org.jboss.remoting.transport.socket.ServerThread.run(ServerThread.java:239)
But that is exactly what I´m wanting: Saving a detached entry ;-)
What I´m doing wrong?
Regards
---
Joachim
The Entity Bean
package com.toolsforjobs.j2ee.test.server.domain;
import java.io.Serializable;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.OneToOne;
import javax.persistence.Transient;
@Entity
public class Debtor implements Serializable{
@Transient
private static final long serialVersionUID = 3154162344396113561L;
int id;
String idAtCustomer;
double balance;
//Address address;
/*
@OneToOne(cascade={CascadeType.ALL})
public Address getAddress() {
return address;
}
*/
public double getBalance() {
return balance;
}
@Id @GeneratedValue
public int getId() {
return id;
}
public String getIdAtCustomer() {
return idAtCustomer;
}
/*
public void setAddress(Address address) {
this.address = address;
}
*/
public void setBalance(double balance) {
this.balance = balance;
}
public void setId(int id) {
this.id = id;
}
public void setIdAtCustomer(String idAtCustomer) {
this.idAtCustomer = idAtCustomer;
}
}
The Stateless Session Bean
package com.toolsforjobs.j2ee.test.server;
import javax.ejb.Stateless;
import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import com.toolsforjobs.j2ee.test.server.domain.Debtor;
@Stateless
public class DebtorAgentBean implements DebtorAgentRemote {
@PersistenceContext(unitName="tfj-dbs") EntityManager manager;
public Debtor findDebtor(int id) {
return manager.find(Debtor.class, id);
}
public void saveDebtor(Debtor deb) {
manager.persist(deb);
}
}
And the calling client
package com.toolsforjobs.j2ee.test.client;
import javax.naming.Context;
import javax.rmi.PortableRemoteObject;
import com.toolsforjobs.j2ee.test.server.DebtorAgentRemote;
import com.toolsforjobs.j2ee.test.server.domain.Address;
import com.toolsforjobs.j2ee.test.server.domain.Debtor;
public class DebtorClient {
public static void main(String[] args) {
try {
Context jndiContext = getInitialContext();
Object ref = jndiContext.lookup("DebtorAgentBean/remote");
DebtorAgentRemote dao = (DebtorAgentRemote) PortableRemoteObject.narrow(ref, DebtorAgentRemote.class);
Debtor deb1 = new Debtor();
deb1.setId(1);
deb1.setBalance(100.0d);
deb1.setIdAtCustomer("toolsforjobs");
dao.saveDebtor(deb1);
} catch (javax.naming.NamingException ne) {
ne.printStackTrace();
}
}
public static Context getInitialContext() throws javax.naming.NamingException {
return new javax.naming.InitialContext();
}
}