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(); } }