Eneris Solutions Oy

Eneris Solutions » SEAM Performance

Seam performance. If you don't know what SEAM is -- then turn around and go back to the technologies pages and start reading...


Now I now what the bogeyman of Seam is – performance.

Don't get me wrong... I love Seam. But if you don't THINK about what you are doing, you can really shoot youself in the foot when it comes to performance. If you are just wacking together some little low-volume apps, then you can skip this whole discussion.


EJB3 was designed to be a business layer, with support for transactions, security, etc., etc. When you break down the barrier, or essentially merge, the business logic layer with the presentation layer you should think carefully about what you are doing. Granted that doing so solves the lazy loading problem, but then again, if any of your clients were remote, the lazy-loading couldn't work anyways.

Performance killers: facelets, ajax, bi-jection, client-side state, transactions. Oops, I think I listed most of the features of Seam.

I tried to re-read all the statements by Gavin King, et. al. And to really read between the lines, because sometimes they are overly polite. It might be easier if they just wrote something like: don't do this, or don't do that.

Most importantly, understand that if you are using EJB3 and Seam beans that EVERY SINGLE METHOD CALL must go through the interception chain. These interceptors are where the magic happens, i.e. Bijection, transactions, etc.

So here is my list for performance:

  1. use server-side state. For some reason we started using client-side because of some bugs in faclets somewhere.

  2. Increase the facelets buffer.

  3. Don't use bijection too much. Is it really so hard to have a method getPersons() which then has a null check to avoid the need for the factory. Added benefit of this is that you will know that the scope is the same as the bean that you are getting the data from. Whenever I outject something I can't seem to figure out which scope it goes to, because it can live longer than the owner.

  4. Datatables seems to be our #1 problem. When datatables call methods on the class, instead of using a method on the data model that you are iterating over. As I understand it, each call back to the class will cause the interceptors to run, and there is no way to disable it. However, if you just access a property of your iteration variable then you are not triggering interception. I need to run some timing tests on this one.

  5. Same as previous – keep you El clean in the JSF page.

  6. I guess you almost have to use the extended persistence context. Otherwise, gee, you will be triggering a transactions on every getter and setter method – baaad. I wish they would just write that in big text IF YOU DON'T USE HIBERNATE EXTENDED PERSISTENCE CONTEXTS YOU WILL KILL YOUR PERFORMANCE.

  7. The biggest problem I have with extended persistence contexts is refreshing the data before the end of a transaction. User's nowadays want to see changes in real time even though they are in the middle of doing something else. I guess I could use the event mechanism to get notified about changes, and then update only when I need it. So currently I am manually flushing objects from the conversation each time a refresh comes in. This seems really stupid....

  8. Don't use REST style architectures when you will have complicated state. Your urls will become unmanageable.

  9. More to come... 
  10. and
  11. more
  12. and Email me if you need help! thomas@eneris.com


I think we have this configured for using one transaction per method call, but there is an extended persistence context. So the objects are managed, i.e. Cached in the persistence context, and then each page refresh (and ajax call) a transaction is started, and then ended after the page is rendered.

With seam we can keep the persistence context valid, i.e., the objects are still managed, and then commit changes at the end of a conversation. That allows us to do different things in web requests changing states of objects, but buffer the changes until the commit. Can we get new data during this?

How to fix this?

  • Update the data only when we need to.

  • Use transactions only when we need one.

I guess we talk about transactions, to mean exactly the same thing as database session. Back in JDBC days I could open a session, and fetch data without a transaction. Transactions were for changing things. Why is it nowadays, that everything is always a transaction?

Confusion about transactions and persistence context – gee I wonder why? Let's see, there seems to be about 8 different ways to do these in SEAM.

Use a FLUSH_MANUAL, for those tricky conversations. Will this mean there are only transactions when I want them? 

Another 'not-talked-about' problem with Seam. The compile-try cycle is very slow. Restarting jboss is slow. This might be the #1 problem nowadays. So either get yourself a big machine, or suffer.

You can get a little better turnaround time by using EXPLODE instead of deploy. This way at least if you are only making UI changes (to JSP/JSF) pages you will not need to restart jboss. This is a lifesaver!