-
1. Re: @Begin and @End
gavin.king Jul 19, 2006 2:13 PM (in response to bluetrade)If you really _have_ to have transparent lazy fetching of data off of the user, combined with caching of that data then create a session-scoped managed persistence context.
There are a couple of ways to do this, but the easiest is to use Seam 1.1 CVS build and throw the following in components.xml:<component name="userDatabase" scope="session" class="org.jboss.seam.core.ManagedPersistenceContext"> <property name="persistenceUnitJndiName">java:/myEntityManagerFactory</property> </component>
Alternatively, an approach I prefer is to only store the userId in session scope, and create an event-scoped manager component for the actual User, that pulls the User out of the (conversation-scoped) persistence context, ie:@Scope(EVENT) @Name("user") public class ManagedUser { @In(create=true) private EntityManager myDatabase; @In String userId; @Unwrap public User getUser() { return myDatabase.find(User.class, userId); } }
Now, of course you won't get caching of the 100 dependent objects in the session scope, but they do at least get cached in the conversation scope. You will never experience LIEs, as long as you always refer to the dependent objects by injecting the User and then navigating. -
2. Re: @Begin and @End
gavin.king Jul 19, 2006 2:14 PM (in response to bluetrade)P.S. Note that it is never OK to have a conversation that spans an entire login session.
-
3. Re: @Begin and @End
gavin.king Jul 19, 2006 2:17 PM (in response to bluetrade)P.P.S. I've seen a couple of people ask about this - would someone please be so kind as to write these solutions up for the Wiki?
Thanks -
4. Re: @Begin and @End
gavin.king Jul 19, 2006 2:32 PM (in response to bluetrade)Note: I just updated the post to reflect that the manager component need only be EVENT scoped, not CONVERSATION-scoped as I originally wrote.
-
5. Re: @Begin and @End
gavin.king Jul 19, 2006 2:46 PM (in response to bluetrade)Hmmmmm, I just created a generic ManagedEntity component. Kinda cool, possibly useful. You use it like this:
<component name="user" class="org.jboss.seam.core.ManagedEntity"> <property name="entityClass">com.myapp.User</property> <property name="entityManager">#{myEntityManager}</property> <property name="id">#{userId}</property> </component>
Or even like this:<component name="blogEntry" class="org.jboss.seam.core.ManagedEntity"> <property name="entityClass">com.myapp.BlogEntry</property> <property name="entityManager">#{myEntityManager}</property> <property name="id">#{params['blogEntryId']}</property> </component>
And then, whenever the id of the object is available in a context variable or request parameter, we can just inject the correct instance.
Kinda cool, I think.... -
6. Re: @Begin and @End
bluetrade Jul 19, 2006 6:52 PM (in response to bluetrade)Hi Gavin,
thanks for your help. Just one last question, is it ok to still keep the user in every (I need it in almost every bean) around via @In @Out User user - I will always then have an @End around the "last"-logic steps...
Is there a way to "profile"/"monitor" a seam application to see directly what is in memory and how the transactions are handled? That would be useful for me to understand the whole scenario...
THANK YOU SOOO MUCH GAVIN!!!! Seam is great
Joey -
7. Re: @Begin and @End
gavin.king Jul 19, 2006 7:29 PM (in response to bluetrade)is it ok to still keep the user in every (I need it in almost every bean) around via @In @Out User user
I don't quite understand. With this mechanism you never need @Out. You can do @In(create=true) User user as much as you like.Is there a way to "profile"/"monitor" a seam application to see directly what is in memory and how the transactions are handled? That would be useful for me to understand the whole scenario...
There is the Seam debug page, but that does not tell you anything about transactions... -
8. Re: @Begin and @End
bluetrade Jul 19, 2006 11:21 PM (in response to bluetrade)Thanks,
sorry, of course Out won't be used...
Joey -
9. Re: @Begin and @End
holgerprause Jul 20, 2006 1:05 AM (in response to bluetrade)"gavin.king@jboss.com" wrote:
If you really _have_ to have transparent lazy fetching of data off of the user, combined with caching of that data then create a session-scoped managed persistence context.
There are a couple of ways to do this, but the easiest is to use Seam 1.1 CVS build and throw the following in components.xml:<component name="userDatabase" scope="session" class="org.jboss.seam.core.ManagedPersistenceContext"> <property name="persistenceUnitJndiName">java:/myEntityManagerFactory</property> </component>
Hello, i want to use the approache mentionend above but i have some questions regarding this.
1)
What does "myEntityManagerFactory" means in this context, is that the value of the "jboss.entity.manager.factory.jndi.name" property described in my persistence.xml ?<property name="persistenceUnitJndiName">java:/myEntityManagerFactory</property>
2) how can i use this(java side)?
Should i use
@PersistenceContext
private EntityManager em;
or (adepting your example nr1)
@In(create=true)
private EntityManager userDatabase;
Thank u very much,
Holger -
10. Re: @Begin and @End
baz Jul 20, 2006 5:22 AM (in response to bluetrade)And then, whenever the id of the object is available in a context variable or request parameter, we can just inject the correct instance.
Hi Gavin,
i have tried your approach with a ManagedHibernateEntity.
i must learn what the word 'whenever' means:
if the id is not available i get an exception11:03:13,156 DEBUG org.jboss.seam.Component: instantiating Seam component: bazProject 11:03:13,156 DEBUG org.jboss.seam.Component: initializing new instance of: bazProject 11:03:13,218 DEBUG org.jboss.seam.Component: seam component not found: bazProjectID 11:03:13,234 DEBUG org.hibernate.jdbc.JDBCContext: successfully registered Synchronization java.lang.IllegalArgumentException: id to load is required for loading at org.hibernate.event.LoadEvent.<init>(LoadEvent.java:51) at org.hibernate.event.LoadEvent.<init>(LoadEvent.java:33) at org.hibernate.impl.SessionImpl.get(SessionImpl.java:796) at org.hibernate.impl.SessionImpl.get(SessionImpl.java:792) at org.jboss.seam.core.ManagedHibernateEntity.getInstance(ManagedHibernateEntity.java:52)
Does it make sense to you to write getInstance in this way?@Unwrap public Object getInstance() throws ClassNotFoundException { Class clazz = Class.forName(entityClass); if (id==null) return null; return session.get(clazz, id); }
Ciao,
Carsten -
11. Re: @Begin and @End
gavin.king Jul 20, 2006 1:32 PM (in response to bluetrade)What does "myEntityManagerFactory" means in this context, is that the value of the "jboss.entity.manager.factory.jndi.name" property described in my persistence.xml ?
Yes, ofcourse.2) how can i use this(java side)?
@In(create=true) private EntityManager userDatabase;
-
12. Re: @Begin and @End
gavin.king Jul 20, 2006 1:51 PM (in response to bluetrade)"baz" wrote:
Does it make sense to you to write getInstance in this way?@Unwrap public Object getInstance() throws ClassNotFoundException { Class clazz = Class.forName(entityClass); if (id==null) return null; return session.get(clazz, id); }
mmmmmm, do you really need it to work like that?
It makes it unclear what "null" means ... does null mean "no id", or does it mean "no object for the id". -
13. Re: @Begin and @End
baz Jul 21, 2006 1:37 AM (in response to bluetrade)Hello Gavin.
It makes it unclear what "null" means ... does null mean "no id", or does it mean "no object for the id".
When getInstance is called and there is no Id in any context, session.get is not callable. So the if statement should ensure the pre condition for session.get.
My object which i want to manage is choosen by the user. When the user select the object i set the Id in the appropriate context.
In my app i do not know when a user has the selected the object. So it is possible that i reference this object when no id is set.
Concrete: On each of my pages i have to display the project number of the bazProject the user works on. But as long as the user has not choosen a project, the bazProjectID id will be null.
Ciao,
Carsten -
14. Re: @Begin and @End
baz Jul 22, 2006 3:37 AM (in response to bluetrade)Hi Gavin,
i will change back to my own manager, if you have the opinion that my change does not make sense.
IMHO, it can always happen that 'getInstance()' from the Manager is called when there is no Id in any context. This will result in an exception. But if there is no Id than there is no object. And this must not be an error.
Ciao,
Carsten