-
1. Re: Page Parameters, @Factory and persisting
gonorrhea Feb 15, 2009 4:14 PM (in response to haljohnson)post your code
-
2. Re: Page Parameters, @Factory and persisting
haljohnson Feb 15, 2009 5:01 PM (in response to haljohnson)I was rather hoping to avoid that, since this is more of a general design question (I don't want to get into bad habits from the beginning). But I appreciate your time, and I will type out as simple of an example as I can here to illustrate my problem.
Say I have a simple Entity bean:
@Entity public class Info { private Integer id; private String text; @Id public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } public String getText() { return text; } public void setText(String text) { this.text = text; } }
I also have a simple helper pojo, providing a store for a page parameter as well as a factory for the Info entity:
@Name("infoHelper") public class InfoHelper { private Integer id; @In EntityManager em; public Integer getId() { return id; } public void setId(Integer id) { this.id = id; } @Factory(value="info", scope=ScopeType.CONVERSATION) public Info getInfo() { return em.find(Info.class, getId()); } public String save() { em.flush(); } }
And an excerpt from pages.xml:
<page view-id="/whatever.xhtml"> <param name="id" value="#{infoHelper.id}"/> </page>
And in whatever.xhtml, I'd have something like:
<h:form> <h:inputText value="#{info.text}"/> <h:commandButton value="Save" action="#{infoHelper.save}"> <f:param name="id" value="#{infoHelper.id}"/> <s:conversationPropagation/> </h:commandButton> </h:form>
The problem now is the
info
component is disappearing by time InfoHelper.save gets called. Theid
page parameter is not propagating, so the factory method is settinginfo
to null.Shouldn't
info
remain in the conversation context until the post request from the commandButton? If it is in the conversation context, why is the getInfo() method being called? From the documentation I gathered that the factory method is only called when the component doesn't exist.Thanks in advance for any help!
-Hal
-
3. Re: Page Parameters, @Factory and persisting
haljohnson Feb 15, 2009 5:05 PM (in response to haljohnson)PS - The InfoHelper.save() method does return a value, I've tried returning null,
/default.xhtml
, etc to no avail. I typed this out from memory so I apologize for any other simple typos. -
4. Re: Page Parameters, @Factory and persisting
binnyg Feb 16, 2009 2:41 AM (in response to haljohnson)What you read about factory annotation is correct. Factory method is only called if the value is null.
In your factory method, getId() always returns null and hence entityManager cannot find Info object.
@Factory(value="info", scope=ScopeType.CONVERSATION) public Info getInfo() { return em.find(Info.class, getId()); }
You can verify if info object is available in debug page. Enable seam debugging in components.xml with
<core:init debug="true" />
-
5. Re: Page Parameters, @Factory and persisting
haljohnson Feb 16, 2009 6:58 AM (in response to haljohnson)Thank you for your response Binesh, but I think you may have misunderstood. I'll try to make my problem a bit clearer.
Say I request a page, such as:
/whatever.seam?id=1
This is fine, the page will load, it will find the proper record, and the factory method will create the correct Info object.
The problem occurs when I press the form button to save the changes to the text field. By time the save method is called, the
info
component is gone and I'm not sure why. It should be in the conversation context, and from my understanding, the conversation context should exist until the save method is called (when the POST request is being handled).The getInfo() method will return null at this point, since the page parameter isn't propagating (this is the second part of my problem, but I'd like to work out one bit at a time). But the
info
component should still exist, so the factory method shouldn't even be called.What am I doing wrong? Why isn't the
info
component still in the conversation context for my save call?I know I'm missing something fairly fundamental, so please bear with me, and thank you for any help!
-Hal
-
6. Re: Page Parameters, @Factory and persisting
marcioendo.marcioendo.gmail.com Feb 16, 2009 2:18 PM (in response to haljohnson)
I have a simple Entity bean with an id and a character field. I have a page parameter that associates the id with a property of a helper seam component (pojo). This component has a @Factory annotated method that creates the Entity bean by looking up the id (from the page parameter). A single <h:inputText> on the page is associated with the character field in the Entity bean.This sounds like exactly what an EntityHome does.
I'd suggest you create a simple project with seam-gen and look at the generated Java code and .xhtml pages. It will give you hints on how this could be accomplished.
Apart from that, IIRC, <h:commandButton> does not take <f:param> as a child element. That is one of the reasons why <s:button> was created. Also, it sounds like you are not explicitly starting any conversation; without that, any modifications you make will be lost.
-
7. Re: Page Parameters, @Factory and persisting
binnyg Feb 16, 2009 4:29 PM (in response to haljohnson)s:button will not submit the form. You can use a4j:commandButton and a4j:actionParam.
Even though starting a conversation will solve many problems this is not the only way to modify data.If you are looking for a standard to do CRUD operations in your application I agree with Marcio that you should use seam-gen to create your project and see how everything is wired together.
Your InfoHelper is not conversation scoped and when you click on save button it doesn't not participate in the same conversation. How it works is, seam starts a temporary conversation every request and if your bean is conversation scoped then your long running conversation and the temporary conversation is merged and you will have access to your values.
Does it make sense?
-
8. Re: Page Parameters, @Factory and persisting
haljohnson Feb 16, 2009 4:30 PM (in response to haljohnson)Thank you for taking the time to reply Mario. In an effort to further my understanding of what should be exceedingly basic behavior, I recreated my issue with as minimal of an implementation as possible. Not too surprisingly it works fine as is, which means I have something conflicting with my original implementation. This is entirely my fault and I will have to spend some time dwelling on what is causing the problem.
I had a feeling <h:commandButton>'s didn't use <f:param> child elements, but I was at the stage of trying any and everything to solve the problem.
I had come across the EntityHome class during my learning endeavors, but haven't investigated it yet. I will do so at my first opportunity since you mentioned it may fit the functional pattern I am looking for. Perhaps it will provide a more elegant approach.
Thank you again, take care!
-Hal
PS - After originally reading your response, I tried starting a long running conversation with @Begin on the InfoHelper.save() method, but it made no difference. Turns out the temporary conversation is all that seems to be necessary (thought I remembered reading in the docs that it persists across JSF callbacks, and it does in fact seem to).
-
9. Re: Page Parameters, @Factory and persisting
haljohnson Feb 16, 2009 4:37 PM (in response to haljohnson)Thank you as well Binesh, did not notice your reply until after I made my last post.
I never expected the InfoHelper bean to persist, although it looks at first glance like it stores state (getId/setId), that property just exists to hold the page parameter during the request. It was the
info
component the factory created that I was trying to use as a backing bean for the form.As I mentioned in my previous response, I created as minimal of an implementation as possible and it works as I figured it should. This means I have something somewhere conflicting with the original code.
I appreciate your time and help, and apologize for what was apparently my own mistake. Now I just need to locate it. :)
Best wishes.
-Hal