1

I have a controller where the user fills in information into a form. On saving the form, JPA objects are created and persisted to a database and the user is redirected to another controller to view the form. I am not interested in passing the whole objects between the controllers, just Strings that represent the objects. I could reload the objects from the database, but due to slow load times, is there any way I can pass data without accessing the DB?

Edit: When one controller redirects to another, I am interested in "sending" strings from the first controller to the redirected controller so that those strings can be displayed.

Thank you for the help!

Edit 2:

Here's the code in the first controller:

//Called by a commandButton
public String saveForm() {
    //Objects are created and persisted to DB
    //Store the Objects' names as strings. These are the values I want to access in the second controller
    return "view_form.jsf?formId=" + formId.toString() + "&faces-redirect=true";
}

In the second controller called viewForm, I'm loading the formId with viewParam:

<f:metadata>
  <f:viewParam name="formId" value="#{secondController.formId}" required="true"/>   
  <f:event type="preRenderView" listener="#{secondController.loadForm}"/>
</f:metadata>

In loadForm I would like to access the Strings created in saveForm. I'm currently looking at the link Rodmar Conde posted about storing the data in the Session Map. Is this the correct way to go about this?

Thank you for your help so far!

Jrokisky
  • 65
  • 1
  • 10
  • 1
    I'm not sure if I understand your concrete problem. If you mean passing data between viewscoped beans like as in `action="#{otherBean.doSomething(oneBean.entity)}"`, then this data is not exposed in HTML/HTTP in any way and can impossibly affect "load times". Please clarify the concrete problem. – BalusC Apr 05 '13 at 13:55
  • @BalusC I've edited my question to be more descriptive. – Jrokisky Apr 05 '13 at 14:16
  • Is this really a redirect to a new GET request or a navigation (forward) on postback? – BalusC Apr 05 '13 at 14:19
  • You can save the strings into the HttpSession object while being in controller1 and then you can recover them while being in controller2. [Saving data to session in JSF](http://stackoverflow.com/questions/1282251/saving-data-to-session-in-jsf) – Rodmar Conde Apr 05 '13 at 14:29
  • @BalusC I'm not entirely sure if I understand the difference. When the 'Save' commandButton is pressed, an action in my backing bean is called, and I plan on redirecting to the other controller/page from there. Sorry for the lack of clarity, I have just started to work with JSF/JEE. – Jrokisky Apr 05 '13 at 14:31
  • Refer http://stackoverflow.com/questions/11277366/what-is-the-difference-between-redirect-and-navigation-forward-and-when-to-use-w In future questions, some concrete code about how you're currently performing the job would be helpful to see what you really mean. – BalusC Apr 05 '13 at 14:53
  • @BalusC I've added some code. I looked at the link you provided and it led me down a rabbit hole of interesting questions. You're contributions have answered many questions that I had! – Jrokisky Apr 05 '13 at 16:09
  • Okay, I see what you're getting at. The code looks fine. This is also the recommended approach for the case it's an idempotent request. Your real problem is apparently just the DB performance (although a single select on a properly indexed table should be relatively cheap). Introducing kind of 2nd level cache in persistence layer may help a lot. Refer the documentation of persistence layer in question using the keywords "second level cache" or "L2 cache". This is however beyond the scope of JSF. Abusing the JSF session scope is another way, but not the right one. – BalusC Apr 05 '13 at 16:18
  • @BalusC thank you! I'm going to talk to my supervisor about implementing a 2nd level cache. Would you like to post your last comment as an answer so I can mark it accepted? – Jrokisky Apr 05 '13 at 16:27
  • I posted it. Can you please remove "solved" from title? That's not the way how it works here. Just mark the answer accepted and it'll already appear differently in the listings and be searchable as such. You're here on a full fledged Q&A site, not an old fashioned discussion forum :) – BalusC Apr 05 '13 at 16:31

2 Answers2

1

The code looks fine. This is also the recommended approach for the case the target page needs to be opened by an idempotent request. See further also How to navigate in JSF? How to make URL reflect current page (and not previous one) for some general hints.

Your real problem is apparently just the DB performance (although a single select on a properly indexed table should be relatively cheap, sure that it isn't just the connection cost (use connection pool) or the network latency (host DB server near to web server)). Introducing kind of 2nd level cache in persistence layer may help a lot. Refer the documentation of persistence layer in question using the keywords "second level cache" or "L2 cache".

Note that this is beyond the scope of JSF. Abusing the JSF session scope is another way, but not the right one. Sharing data between two view scoped bean instances separated by a GET request is not possible as their lifecycle ends and starts with a GET request. See also JSF ViewScoped variable not surviving redirect to same page.

Community
  • 1
  • 1
BalusC
  • 1,082,665
  • 372
  • 3,610
  • 3,555
0

Here is what i settled for. Save the values in the session as below in the first ViewScoped controller:

ExternalContext etx = FacesContext.getCurrentInstance().getExternalContext();
    HttpServletRequest httpReq = (HttpServletRequest)etx.getRequest();
    HttpSession session = httpReq.getSession();
    session.setAttribute("formId", "formId_value_here"); //use a map if you have multiple values

And retrieve the value in the PreRenderView of the second ViewScoped controller (or anywhere) as below:

ExternalContext etx = FacesContext.getCurrentInstance().getExternalContext();
HttpServletRequest httpReq = (HttpServletRequest)etx.getRequest();
HttpSession session = httpReq.getSession();
String formId = (String)session.getAttribute("formId");

Hope this helps someone.

Tunde Michael
  • 364
  • 4
  • 8