• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Campbell Ritchie
  • Liutauras Vilda
  • Jeanne Boyarsky
  • Devaka Cooray
  • Paul Clapham
Sheriffs:
  • Tim Cooke
  • Knute Snortum
  • Bear Bibeault
Saloon Keepers:
  • Ron McLeod
  • Tim Moores
  • Stephan van Hulst
  • Piet Souris
  • Ganesh Patekar
Bartenders:
  • Frits Walraven
  • Carey Brown
  • Tim Holloway

JSF & JTA Transaction

 
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi,

Is it possible when we call a jsf action on an inner bean to have a JTA transaction active ? ELResolver ? Interceptor ?
Here Load & Flush : An exception is raised . No transaction is in progress.
When EL resolves #{entity2Bean.innerBean} => a JTA is opened and closed to get innerBean.
But the JTA Transaction is not still active when the method flush is called.
I've posted this question on Hibernate Forum nut nobody gives me a solution ...

Any Ideas ?

Thanks

Amon



 
Bartender
Posts: 20842
125
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Welcome to the Ranch, Sebastian!

I'm not sure if your first bean is supposed to be a traditional Hibernate entity or a JPA Entity (looks like the latter), but in either case, Entity objects do not work well as primary backing beans. The JSF bean factory can only manufacture blank beans - it cannot fetch. In fact, JSF has no persistence knowledge at all.

A top-level backing bean, in short, should be a simple POJO, with no persistence properties of its own.

The top-level bean, however, can acquire Entity beans as secondary (property) objects, both singly and in collections (for example as the rows of a DataModel). However, I keep my actual persistence logic in a completely separate layer of the webapp.

I actually have 2 persistence layers: the upper one, which is the one that the business logic invoked by action methods uses. That layer is responsible to locating and CRUD functions on heterogeneous sets of data. For example, a "working set" for a JSF business method might have a Company bean, a Department Bean(s) and employee beans, all of which would be affected by the current action. The upper persistence layer (commonly known as the "service layer") runs its methods as wholly-contained transactions. The working set is returned from the service layer method as detached objects, which makes them simple POJOs. The next time a service layer method is invoked for that collection of objects, it will have started a transaction, merged (re-attached) the incoming data, then do any other operations necessary.

The bottom persistence layer is my DAO layer, and it is exclusively for the use of the Service layer. Each DAO object does finder and CRUD on just one table or a parent-child table.

Because I'm working with detached beans in the JSF code, I don't have to worry about transaction context in the JSF code or business methods. I also don't have to worry about accidentally zapping something that I didn't want updated and I don't have to worry about the details of the persistence infrastructure in regard to the different stages of the JSF lifecycle. And my JSF logic never has do deal with the EntityManager.

 
Sebastien Moisan
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

Thanks for giving me some advices for my case.

I've not the same vision for using "detached" objects ; for me, you have to keep your business entities in sync
so that your UI will automatically grab all the differents relationships of the object without having to build some unnecessary POJO objects.
It's necessary to have a flush mode in manual to be sure that the entity is not saved in case the user have just updated the data in the view without persisting the data.

I've found a workaround in my case to have a correct JTA transaction running.
I will try to have a more generic code for the implementation ;  the idea is to force the upper bean to respond to jsf actions (a jta transaction is opened / closed around this method) and to call the listener in that method.

Sebastien

 
Tim Holloway
Bartender
Posts: 20842
125
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Likes 1
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I think you've missed something essential about the web.

A web application is not a continuously-running program like a stand-alone Java application is. A web application is a collection of service routines (rather like a Windows DLL) that processs one-shot requests from clients and return responses. One request, one response. No more, no less. Once the client has received a response from the server it it disconnected from the server until it opens another connection to make another request and receive another response. Repeated as necessary. Responses are never unsolicited. For every response sent, there was a request that demanded it.

Web application servers are designed to make efficient use of resources by not tying them up when they are not actively being used. The Thread that a Java servlet runs under (and this includes the FacesServlet) does not belong to either the servlet or to the user. It is pulled from a service Thread pool when the server receives an HttpServletRequest, dispatches the Servlet's process() method (which in turn may call doGet, doPost, etc. and when the process() method returns, the Thread it ran under is returned to the Thread pool until some other HttpServletRequest needs to run. That request may be for a completely different web application and/or a completely different user. This is why servlets are forbidden by the J2EE spec to spawn their own child Threads.

A LOT of Http service objects get created and destroyed or serialized between HttpServletRequests. If they hold on to excessive resources between requests, they consume memory and/or network and file resources that could be better saved to increase the overall capacity of the server. That's why you want to keep the size and number of objects in the HttpSession to a minimum. It's far more efficient overall to re-inflate your working resources when you are actively processing a request than to be a dog in the manger and hoard stuff.

Incidentally, the JSF component tree itself doesn't pass unscathed between requests. It's collapsed down and re-constructed for each new incoming request. And the FacesContext doesn't exist at all except when the FacesServlet is processing.

JPA was explicitly designed with this sort of paradigm in mind. The EntityManager gets a Connection from the server's database Connection Pool, processes, then returns the Connection to the pool, allowing other users/apps to share the Connection (since obtaining Connections from scratch is extremely expensive). A performance-sensitive application system also takes advantage of caching, either within the webapp (done by JPA) or from an external cache, or sometimes both. Nothing is gained by having the application hold connected objects - a JPA Entity object's hash() method by definition returns a value that can used to locate an object in cache just as rapidly (and by much the same means) as Session scope objects are located. So you're looking for the illusion of efficiency and in the process, basically throwing a spanner into the JPA's own designed in efficiencies.

I mentioned that one reason I work with detached objects is that it's harder to accidentally nuke incidental data, but another, more compelling reason is the JSF lifecyle. I learned long ago (before JSF was even invented - or JPA for that matter) that holding attached ORM objects between the different stages even in a basic roll-your-own servlet-to-JSP architecture can get you into real trouble.
 
Sebastien Moisan
Greenhorn
Posts: 3
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
Hi Tim,

I will rethink my app to eventually change some components or some way of design.
Thanks for sharing your own experience.

Sebastien
 
Tim Holloway
Bartender
Posts: 20842
125
Android Eclipse IDE Tomcat Server Redhat Java Linux
  • Mark post as helpful
  • send pies
  • Quote
  • Report post to moderator
I won't say that my strategy is the One True Way of doing things, but it is the culmination of years of learning by experience. Because it's based on clear assignment of duties and separation of concerns, it's fairly easy to design, debug, and maintain - including dumping the maintenance off on someone else who's not familiar with my code when I'm tired of it. :)

Continuous connection was something I abandoned very early, though. It was just too much trouble. Things would break in all sorts of random places.
 
  • Post Reply Bookmark Topic Watch Topic
  • New Topic
Boost this thread!