[jboss-user] [JBoss Seam] - EntityManager and Conversation contex
Kruno
do-not-reply at jboss.com
Sun Apr 8 10:25:05 EDT 2007
I read both books Seam Contextual components and JBoss® Seam: Simplicity and Power Beyond Java? EE from Safari but I can't seem to find the answer.
I was under impression that persistence context is the same as hiberante session and that if @PersistenceContext(type = EXTENDED) that it would last during conversation, and that it would be shared between EntityManagers from two different action beans if they are in the same conversation.
I hope sample code would explain better my question:
I made a little example.
first there are two entity beans directory and file
directory has a set of files
Directory:
| package orka.test;
|
| import java.util.LinkedHashSet;
| import java.util.Set;
|
| import javax.persistence.CascadeType;
| import javax.persistence.Entity;
| import javax.persistence.GeneratedValue;
| import javax.persistence.GenerationType;
| import javax.persistence.Id;
| import javax.persistence.OneToMany;
| import javax.persistence.Table;
|
| import org.jboss.seam.annotations.Name;
|
| @Entity
| @Name("directory")
| @Table(name="directory")
| public class Directory {
|
| @Id
| @GeneratedValue(strategy=GenerationType.TABLE)
| private long sifra;
|
| private String name;
|
| @OneToMany(cascade={CascadeType.ALL},mappedBy="directory")
| private Set<File>files= new LinkedHashSet<File>();
|
|
|
|
| public Set<File> getFiles() {
| return files;
| }
|
|
| public void setFiles(Set<File> files) {
| this.files = files;
| }
|
|
| public long getSifra() {
| return sifra;
| }
|
|
| public void setSifra(long sifra) {
| this.sifra = sifra;
| }
|
|
| public String getName() {
| return name;
| }
|
|
| public void setName(String name) {
| this.name = name;
| }
|
|
|
| }
|
|
File:
| package orka.test;
|
| import javax.persistence.Entity;
| import javax.persistence.GeneratedValue;
| import javax.persistence.GenerationType;
| import javax.persistence.Id;
| import javax.persistence.JoinColumn;
| import javax.persistence.ManyToOne;
| import javax.persistence.Table;
|
| import org.hibernate.validator.NotNull;
| import org.jboss.seam.annotations.Name;
|
|
| @Entity
| @Name("file")
| @Table(name="file")
| public class File {
|
| @Id
| @GeneratedValue(strategy = GenerationType.TABLE)
| private long sifra;
|
| @NotNull
| private String name;
|
|
| @ManyToOne
| @JoinColumn(name="directory")
| private Directory directory;
|
|
| //geters seters
|
| public String getName() {
| return name;
| }
|
| public void setName(String name) {
| this.name = name;
| }
|
| public long getSifra() {
| return sifra;
| }
|
| public void setSifra(long sifra) {
| this.sifra = sifra;
| }
|
| public Directory getDirectory() {
| return directory;
| }
|
| public void setDirectory(Directory directory) {
| this.directory = directory;
| }
|
|
|
| }
|
|
Then two action beans: DirectoryActionBean and FileActionBean
DirectoryActionBean:
| package orka.test;
|
| import static javax.persistence.PersistenceContextType.EXTENDED;
|
| import javax.ejb.Remove;
| import javax.ejb.Stateful;
| import javax.persistence.EntityManager;
| import javax.persistence.PersistenceContext;
|
| import org.jboss.seam.annotations.Create;
| import org.jboss.seam.annotations.Destroy;
| import org.jboss.seam.annotations.In;
| import org.jboss.seam.annotations.Name;
| import org.jboss.seam.annotations.Out;
| import org.jboss.seam.log.Log;
|
| @Stateful
| @Name("directoryAction")
| public class DirectoryActionBean implements DirectoryAction {
|
| @PersistenceContext(type = EXTENDED)
| private EntityManager manager;
|
| @SuppressWarnings("unused")
| @org.jboss.seam.annotations.Logger
| private Log log;
|
| @In(required = false)
| @Out
| Directory directory;
|
| public void saveDir() {
| manager.persist(directory);
| }
|
| public String goFiles() {
| return "files";
| }
|
| @Remove
| @Destroy
| public void destroy() {
|
| }
|
| @Create
| public void create() {
|
| directory = new Directory();
| directory.setName("dirOne");
| manager.persist(directory);
|
| }
|
| }
|
|
FileActionBean:
| package orka.test;
|
| import static javax.persistence.PersistenceContextType.EXTENDED;
|
| import javax.ejb.Remove;
| import javax.ejb.Stateful;
| import javax.persistence.EntityManager;
| import javax.persistence.PersistenceContext;
|
| import org.jboss.seam.annotations.Destroy;
| import org.jboss.seam.annotations.In;
| import org.jboss.seam.annotations.Name;
| import org.jboss.seam.annotations.Out;
| import org.jboss.seam.log.Log;
|
|
|
|
| @Stateful
| @Name("fileAction")
| public class FileActionBean implements FileAction {
|
|
| @PersistenceContext(type = EXTENDED)
| private EntityManager manager;
|
| @SuppressWarnings("unused")
| @org.jboss.seam.annotations.Logger
| private Log log;
|
| @In
| @Out
| Directory directory;
|
| public void newFile(){
| File file= new File();
| file.setName("fileOne");
| file.setDirectory(directory);
| directory.getFiles().add(file);
| manager.persist(file);
| }
|
|
| public String backToDir(){
| return "dir";
| }
|
| @Remove
| @Destroy
| public void destroy() {
|
| }
| }
|
|
and at last part of pages.xml:
|
| <page view-id="/directory.jsp">
| <begin-conversation join="true"/>
| <navigation >
| <rule if-outcome="files">
| <redirect view-id="/file.jsp">
| </redirect>
| </rule>
|
| </navigation>
| </page>
|
| <page view-id="/file.jsp">
| <navigation >
| <rule if-outcome="dir">
| <redirect view-id="/directory.jsp">
| </redirect>
| </rule>
|
| </navigation>
| </page>
|
I will not bother you with jsp pages let just say that directory.jsp references only directory entity bean a makes calls only to directoryActionBean it is the same pattern for file.jsp
Now to explain what I do: At first
I create one directory from directoryAction than go to file.jsp and create file, add him in directory and persist file.
After that I return focus to directory.jsp and invoke method save.
Then I get exception
org.hibernate.PersistentObjectException: detached entity passed to persist: orka.test.File
| javax.persistence.PersistenceException: org.hibernate.PersistentObjectException: detached entity passed to persist: orka.test.File
| at org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:647)
| at org.hibernate.ejb.AbstractEntityManagerImpl.persist(AbstractEntityManagerImpl.java:218)
| at org.jboss.ejb3.entity.ExtendedEntityManager.persist(ExtendedEntityManager.java:104)
| at orka.test.DirectoryActionBean.saveDir(DirectoryActionBean.java:33)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.jboss.aop.joinpoint.MethodInvocation.invokeNext(MethodInvocation.java:112)
| at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:166)
| at org.jboss.seam.intercept.EJBInvocationContext.proceed(EJBInvocationContext.java:37)
| at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:55)
| at org.jboss.seam.interceptors.BijectionInterceptor.bijectNonreentrantComponent(BijectionInterceptor.java:79)
| at org.jboss.seam.interceptors.BijectionInterceptor.bijectComponent(BijectionInterceptor.java:58)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
| at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
| at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
| at org.jboss.seam.interceptors.ManagedEntityIdentityInterceptor.aroundInvoke(ManagedEntityIdentityInterceptor.java:36)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
| at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
| at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
| at org.jboss.seam.interceptors.OutcomeInterceptor.interceptOutcome(OutcomeInterceptor.java:21)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
| at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
| at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
| at org.jboss.seam.interceptors.ConversationInterceptor.endOrBeginLongRunningConversation(ConversationInterceptor.java:52)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
| at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
| at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
| at org.jboss.seam.interceptors.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:27)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.jboss.seam.util.Reflections.invoke(Reflections.java:18)
| at org.jboss.seam.intercept.Interceptor.aroundInvoke(Interceptor.java:169)
| at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:64)
| at org.jboss.seam.intercept.RootInterceptor.createSeamInvocationContext(RootInterceptor.java:144)
| at org.jboss.seam.intercept.RootInterceptor.invokeInContexts(RootInterceptor.java:129)
| at org.jboss.seam.intercept.RootInterceptor.invoke(RootInterceptor.java:102)
| at org.jboss.seam.intercept.SessionBeanInterceptor.aroundInvoke(SessionBeanInterceptor.java:50)
| at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
| at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
| at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
| at java.lang.reflect.Method.invoke(Method.java:585)
| at org.jboss.ejb3.interceptor.InvocationContextImpl.proceed(InvocationContextImpl.java:118)
| 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.ExtendedPersistenceContextPropagationInterceptor.invoke(ExtendedPersistenceContextPropagationInterceptor.java:71)
| 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)
| ... 68 more
|
It works fine if I merge directory before persist, but I don't understand why do I have to merge some thing if it was changed in side long running session and it should not have been detached. Maybe I am doing some thing wrong or I did not understand concept of conversation very well.
Like I sad at the beginning I understood that one session could span many request/response cycles and many action beans as long as they are in one conversation and session is long-running.
To merge some thing before persist in some situations is not a big deal, but I would really like to fully understand concepts behind seam
Please Explain!!!
Thanks in advance Kruno.
View the original post : http://www.jboss.com/index.html?module=bb&op=viewtopic&p=4035595#4035595
Reply to the post : http://www.jboss.com/index.html?module=bb&op=posting&mode=reply&p=4035595
More information about the jboss-user
mailing list