Note that there are some explanatory texts on larger screens.

plurals
  1. PO
    text
    copied!<p>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?</p> <p>That said, the pattern really isn't that difficult.</p> <ul> <li>Have a view scoped backing bean</li> <li>Obtain the initial data in an <code>@PostConstruct</code>- (when there are no parameters like IDs) or <code>PreRenderViewEvent</code> method in combination with view parameters</li> <li>Use a separate Service class that uses an entity manager to obtain and save the data</li> <li>Make the entity manager "transaction scoped" <ul> <li>Without EJB/CDI/Spring: <ul> <li>Obtain a new entity manager from an entity manager factory for every operation.</li> <li>Start a (resource local) transaction, do the operation, commit transaction, close entity manager.</li> </ul></li> </ul></li> <li>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.</li> <li>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 <code>merge()</code> on the entity manager.</li> </ul> <p>Realize that outside the service you're working with <code>detached entities</code> 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.</p> <p>The flow for persisting is thus:</p> <pre> <i>View state</i> <i>View scope </i> <i>Transaction scoped PC</i> <b>Facelet/components</b> <b>Backing Bean</b> <b>Service</b> Strings ------> Detached entities --> Attached entities </pre> <p>(the flow for obtaining data is exactly the reverse)</p> <p>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.</p> <p>If you are already adding JSF and JPA to Tomcat, just do yourself a favor and use something like <a href="http://openejb.apache.org/apache-tomee.html" rel="nofollow">TomEE</a>. 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.</p> <p>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).</p> <p>Also see this article, which covers various parts of your requirements: <a href="http://balusc.blogspot.com/2011/09/communication-in-jsf-20.html" rel="nofollow">Communication in JSF 2.0</a></p>
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload