Integrating ice/ace:dataTable with JPA and request-scoped beans - jsf-2

I'm wondering what is the right way to deal with dataTables that take input in a Hibernate/JPA world. As far as I can tell, one of the following three choices is causing the whole house of cards to fall apart, but I don't know which one is wrong.
Semi-automatic transaction and EntityManager handling via a custom JSF PhaseListener that begins and commits transactions around every request
Putting editing components inside a dataTable
Using request-scoped managed beans that fetch their data from a request-scoped EntityManager (with some help from PrettyFaces to set IDs on the request scoped beans from their URLs)
Backing a dataTable with a request-scoped bean instead of a view- or session-scoped bean.
I see an ICEfaces dataTable demo using JPA but they are both manually managing the transactions and not displaying editing components by default. You click on the row which causes an object to be nominated for editability and then when you hit "save" it manually reconnects the object to the new EntityManager before manually triggering a save. I see the click-to-edit function here as giving us a way to ensure that the right object gets reattached to the current session, and I don't know how one would live without something similar.
The impression I'm getting about the new ICEfaces 3.0 ace:dataTable (née PrimeFaces 2.0 dataTable) is that it is intended to be used in a View- or Session-scoped bean, but I don't see how one could get around StaleObjectState and/or LazyInitializationExceptions if one has model objects coming out of the DAO in request A and EntityManager A and then being modified or paged in by request B with EntityManager B.
I suppose it might work under Java EE through some kind of deep fu, but I don't have the luxury of upgrading us from Tomcat 6 to anything fancier right now (though it is my intent in the long run). We're also not about to start using Spring or Seam or whatever the other cool stuff is. ICEfaces is enough weird for us, probably too much weird honestly.
So to sum up, which of these is the wrong choice? The request-scoped entity manager, the request-scoped dataTable or using editing components inside a dataTable? Or is something else really at fault here?

If you'd ask me, the prime fault seems to be sticking to an almost bare Tomcat when your requirements seem to scream for something a little fancier. The mantra is normally that you use Tomcat when you don't need "all that that other stuff", so when you do need it, why keep using a bare Tomcat?
That said, the pattern really isn't that difficult.
Have a view scoped backing bean
Obtain the initial data in an #PostConstruct- (when there are no parameters like IDs) or PreRenderViewEvent method in combination with view parameters
Use a separate Service class that uses an entity manager to obtain and save the data
Make the entity manager "transaction scoped"
Without EJB/CDI/Spring:
Obtain a new entity manager from an entity manager factory for every operation.
Start a (resource local) transaction, do the operation, commit transaction, close entity manager.
Return the list of entities directly from your backing bean, bind the edit mode input fields of the table to the corresponding properties of the entity.
When updating a single row, pass the corresponding entity to the update method of your service. Apart from the overhead of getting an entity manager, starting the transaction etc, this basically only calls merge() on the entity manager.
Realize that outside the service you're working with detached entities all the time. There is thus no risk for any LazyInitializationExceptions. The backing beans need to be in view scope so the correct (detached!) entity is updated by JSF, which your own code then passes to the service, which merges it into the persistence context.
The flow for persisting is thus:
View state View scope Transaction scoped PC
Facelet/components Backing Bean Service
Strings ------> Detached entities --> Attached entities
(the flow for obtaining data is exactly the reverse)
Creating the Service this way is a little tedious and a kind of masochist exercise though. For an example app and just the two methods (get and update) discussed above it wouldn't be so bad, but for any sizable app this will quickly run out of hand.
If you are already adding JSF and JPA to Tomcat, just do yourself a favor and use something like TomEE. This is barely bigger than Tomcat (25MB vs 7MB) and contains all the stuff you're supposedly trying to avoid but in reality need anyway.
In case you absolutely can't upgrade your Tomcat installation (e.g. the product owner or manager thinks he owns the server instead of the developers), you might want to invest in learning about CDI. This can be easily added to your war (just one extra jar) and let's you abstract away lots of the tedious code. One thing that you also could really use is a JTA provider. This too can be added separately to your war, but the more of this stuff you add the better you'll be off by just using TomEE (or alternatives like GlassFish, Resin, JBoss, etc).
Also see this article, which covers various parts of your requirements: Communication in JSF 2.0

Related

EJB taking long time to return data to Backing bean

I have project which JSF 2 and Primefaces 5.2 in frontend. EJB3 and JPA with eclipselink for backend processing deployed on Glassfish 4 server.
Issue: For opening page I am fetching data using postconstruct method in backing bean which inturn calls EJB to get the data from DB.
Data fetches correctly but returning result from EJB to backing bean taking too long time.
Could you please help me on this issue.
It is really hard to give advices with so little informations. Anyway these are my suggestions:
Launch your database monitoring tool and see if the problem is at database level or in the business layer.
Tune your database or the query if necessary, consider using a native query as last option
If you have a large rowset returned, think about pagination, most modern JSF frameworks have components with built in functionalities.
Try to build queries that return just the data you need, es. pk, name, description... etc instead of the whole entity.

BreezeJS - handling lookup tables across modules

We have a large application that allows the user to switch between different modules within the application. Each module needs to be able to save separately, so each module has it's own EntityManager.
There are some lookup tables, though, that we would like to use across the application. If we load the lookup tables at the application level, using a different EntityManager, they are not very usable then within the modules.
For example, if I want to load a 'Countries' lookup table at the application level, I then can't do something as simple as:
Person.Country = lookupDataContext.getCountry('Norway')
if Person is within a module's EntityManager. I will get something like:
"An Entity cannot be attached to an entity in another EntityManager. One of the two entities must be detached first."
Am I understanding BreezeJS correctly? If so, does that mean I need to have the Countries lookup within each module's EntityManager? This seems very limiting.
I believe this question is related to your other question about having multiple EntityManagers. Check out my general thoughts there which cover the scenario you describe here.
To be slightly more specific:
Breeze entities cannot navigate to related entities in a different EntityManager; that's what the error message is telling you.
You probably do want separate instances of the reference entities (such as Countries) in both managers.
You can easily copy any set of entities from one manager to another with export and import methods. You don't have to go back to the server.
Now, instead of a lookupDataContext, each sandbox datacontext can have a sandboxContext.lookups.countries method that delivers the appropriate entities from the proper sandbox manager.
Is this limiting? I don't think it's so bad as long as
you aren't duplicating an enormous amount of data across managers.
the reference entities are essentially immutable during a user session.
a user session doesn't keep too many sandbox managers alive at the same time
you dispose of or re-cycle the sandbox managers (and their datacontexts) when you're done with them.
You should be able to achieve your goal of loading lookups from the server once and managing them centrally in the master manager.
This approach has been very successful in a great number of applications over the last decade (pre-Breeze obviously).
HTH.

EJB3 / JSF2: Design of JSF2 app with ConversationalScope and Stateful EJB

My use case is as follows:
Managing orders with order lines, a customer and payment details.
The app consists of an order list view from which an order detail view can be opened for editing an existing order or creating an new order. The order detail view uses a view param (existing order id or nothing to indicate a new order to be created).
When the order detail view is opened an OrderControllerBean is starting a ConversationalScope and depending on the availability of the order id loading or creating a new order entity. This bean is a stateful session bean as well meant to be used as a facade. The bean contains methods for handling order lines, the customer and the payment details as well as saving and deleting an order. These methods use injected EJBs which are designed as stateless session beans as some kind of DAOs to handle the JPA entities order, order line, customer and payment detail.
From the order detail view with customer info, payment info and order line list the user can navigate to the order line detail view adding/editing order lines and to the customer and payment detail view in a similar manner. Those detail views all use the same OrderControllerBean. On the customer, order line and payment detail views there are Ok and Cancel buttons which are not transactional.
On the order detail view there is a Save and Cancel button which should persist all modifications which are done during the conversation.
The question i have now is: is this design suitable and ok?
I am not sure about the following issues:
What happens if the user never use Save or Cancel?
Does everything stay around till the conversion or the session times out?
What does this mean from the transaction perspective?
What does this mean for the managed entities?
What happens if the user leaves his worksplace and comes back later continuing work on the conversation? If the conversation is timed out, how can i gracefully handle this issue?
Stateful beans are a pain and a source of problems in my opinion.
It's better if you handle timeouts at the http session level, rather than givin this responsibility to the Application server (specially since the http session timeout is still relevant you just add another timeout)
You can replace the persitent state provided by the stateful bean with some kind of object caching or if you prefer you can add a sessionid to the database and keep track of your objects states there (it can be special tables to hold temporary objects until saved or discarded for example).
All in all, keep things apart, timeout and temporary objects on the web server side, and use the ejbs for persistence (JPA) and as a facade (stateless beans)
Why do you need to evaluate the either/or situation in creating orders? There should simply be a button that says : New Order that launches a popup form and another, possibly from a datatable row that says "View Order Details".
The design is fine. Just a few tweaks.
You'll want to create and maintain a single session scoped object(call it Visit) in which you store all session related material. I'd advise you stick with the JSF session scoped bean that is dependent on the http session and can be effectively managed by the container. JSF Session Scoped beans are stored as simple objects in the http session and so can be easily manipulated outside the context of JSF. CDI Session Scoped beans however are trickier to handle outside of CDI.
I'll also advise you break up your order creation process into a multi-step process using dynamically loaded page fragments <ui:include/> or the fine primefaces wizard component. With a multi-step creation, all you need to do is gather data along the steps and only commit a transaction when you've all the info you need from all the steps in a DTO. Keep the wizard DTO in the single session object so the container can cleanup in case of a timeout. If the user never saves or cancel or walks away from his desk, the session will die a natural death. And he can come back and continue his transaction if he makes it in time. Not sure what carlos has against stateless session beans but in my experience, they're a nice way of exposing business processes, in that they can expose their functionality in other ways like webservices and message targets (JEE5). Above all, it's very good design to keep as much business processing out of the managed beans as possible and into durable constructs like EJBs and Spring beans etc.

Struts2 and multiple active wizards / workflows

I'm currently working on a Struts2 application that integrates a wizard / workflow in order to produce the desired results. To make it more clear, there is a business object that is changed on three different pages (mostly with AJAX calls). At the moment I'm using a ModelDriven action (that's extended by all the actions working with the same business object) coupled with the Scope interceptor. While this works okay if the user is handling data for only one business object at a time, if the user opens the wizard for different objects in multiple tabs (and we all do this when we want to finish things faster) everything will get messy, mostly due to the fact that I have only one business object stored in the session.
I have read a few articles about using a Conversation Scope Interceptor (main article) and about using the Scope plug-in (here). However, both approaches seem to have problems:
the Conversation Scope Interceptor doesn't auto-expire the conversations, nor does it integrate properly with Struts2;
the Scope plug-in lacks proper documentation and the last build was made in 2007 (and actually includes some of the ideas written by Mark Menard when he defines his Conversation Scope Interceptor, though it doesn't use the same code).
Spring's WebFlow plug-in seems a bit too complex to be used at the moment. I'm currently looking for something that can be implemented in a few hours time, though I don't mind if you can suggest something that works as needed, even if it requires more time than I'd currently want to spend on this now.
So, seasoned Struts2 developers, what do you suggest? How should I implement this?
Okay this isn't a fully baked idea. But seeing as no else has provided anything, here is what I would start with.
1) See if you can move the whole flow into a single page. I'm a big believer in the less pages is better approach. It doesn't reduce complexity for the application at all, but the user generally finds the interface a lot more intuitive. One of the easiest ways to go about this is by using the json plugin and a lot of ajax calls to your json services.
2) If you must transition between pages (or simply think it is too much client side work to implement #1) then I'd look to the s:token tag. The very first page to kick off a flow will use this tag, which will create a unique value each invocation. You will store a map in your session of model objects. An action will need to be provided with a model by looking it up from the session.
There are a couple challenges with #2. One how do you keep the session from getting too many domain objects? a) Well it might not matter, if the session is set to say six hours you can be rather sure that over night they will get cleared up. b) provided a self management interface which can get/set/list objects in the session. It might be what you thought of at first but it would let a worker do a certain amount and then stop and work on another. If the unit of work has some meaningful name (an invoice number or whatever) it could be quite useful.
A little more sophistication would be to move the model objects out of the session and into the service layer. At which point when inserted you would set an insertion time. You would probably need a manager to hold each type of model object and each manager would have a daemon thread that would periodically scan the map of domain objects and clean out expired ones.
You can figure out more complicated system by kicking a flow off with a token and then using another token on each page. "flowId" and "currentPageId" respectively, then you can graph allowable transitions.
Mind you at this point spring web flow is starting to look pretty good.
There is now a conversation plugin for Struts2 that achieves all these goals with very little work required by the developer: http://code.google.com/p/struts2-conversation/
It has:
-nested conversations
-cleanup of dead conversations
-convention over configuration with annotations and naming conventions
-inherited conversations
-fully integrated with Struts2
-the conversation scope can also be used by Spring IoC container-managed beans
Hope it helps somebody.

JSF 2 Handling Data

I'm developing an app with JSF2 in Tomcat. Still pretty fresh to JSF I have a question which I guess is pretty simple to answer to someone who's got fairly good experience developing web aps and specifically in JSF 2. It's about the way one should store user's data during their interaction with the application. As it stands right now I am saving a lot of data in a session scoped managed bean (like collection of earlier pulled from database entities which themselves are linked to other entities) and whenever a request is made the application will serve anyone of those objects stored in that collection. But I am worried that the session bean is becoming over bloated and don't know how much memory it is safe for a single session bean to consume. What I don't know is whwther when the app goes into production, and a lot of users log, is then the server gonna be ok to handle it. So I guess my question is as follows.
Is there any rule to go buy about storing, handlind and serving large amounts of users data that comes from the database:
Is it ok to do it my way (that is store a lot of stuff in a session scoped bean) so that with each request the app doesn't nee to query and retrieve the data from database. And it that's the case how to best load entities linked to an object stored in a list so they are not all loaded at once but only after the actual object is used to perform some operations before sending the data to the user.
Or should the app keep session beans fairly light (no lists of pre-pulled enities, objects etc) and instead make a trip to the database every time a larger piece of data is required, retrieve it and serve on the fly?
Or perhaps there's an entirely different method, preferred or recommended, to do this.
All suggestions and help are very much appreciated.
You should definitely not do the entity caching job by a JSF session scoped bean. You should delegate the entity caching job to the persistence layer and configure/finetune it over there. JPA and Hibernate for example have pretty good caching support. Here are some articles to read about it:
Javalobby - JPA Caching
EclipseLink Examples - JPA Caching
Hibernate Reference - Chapter 21 - Improving performance
A JSF session scoped bean should merely just contain session scoped data which is used in every request of the webapp throughout the entire browser session. For example, the logged-in user, the user preferences, the user language/locale, etcetera.
The (form) data should just be represented by a JSF request or view scoped bean. Just call the database on every fresh new request or view and do not worry about the costliness of the database trips in your JSF backing bean. Let the persistence layer worry about it.

Resources