StockTracker sample JSF/Spring/Hibernate application posted
About a year ago I did a talk at the DJUG and I had a simple app that I developed for that talk. Well I got busy and never posted it. So I spend the last few days sprucing it up to use the lastest versions of stuff and finaly getting it out the door. I still did not get the templating converted to tiles but it should be straightforward and a great learnign exercise for anyone interested in making that conversion. I'd be happy to post any patches that somone sends to me :-)
I will be doing a public JSF/MyFaces class at the end of the month in San Jose for anyone intrested.
Here is the list of stuff that is used in this example;
- hibernate 3.1 (www.hibernate.org - used hibernate 3.1.2)
- hibernate tools 3.1-beta4
- hibernate annotations 3.1-beta8
- MyFaces 1.1.1 (myfaces.apache.org)
- DBUnit 2.01
- Commons Lang 2.0
- Commons DBCP 1.2.1
- Commons Pool 1.2
- Spring 2.0-m2
- JUnit 3.8.1
- XDoclet 1.2.3 (although should be removed because its only generating a very simple web.xml file)
- MySQL - 4.x or 5.x (I used 5.0.18)
- MySQL JDBC 3.1.12 (not sure if this driver requires 5.0 or not not)
- Tomcat 5.5.15
One interesting thing I ran into is that Tomcat 5.5.15 forces stuff that goes into the session to be serializable (an oversight on my part initially when I wrote the code). A resonable assertion but it apparently was not enforced in 5.0.x or 5.5.9 because I had to make the page objects serializable to get the app to work. I had to look in the localhost.xxxx-xx-xx.log (the xx's are for the date) to find the error that I was getting.
SEVERE: Servlet.service() for servlet jsp threw exception
javax.faces.el.EvaluationException: Cannot get value for expression '#{!menu.userLoggedIn}'
at org.apache.myfaces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:397)
at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:822)
at org.apache.myfaces.renderkit.html.HtmlGridRendererBase.renderChildren(HtmlGridRendererBase.java:176)
at org.apache.myfaces.renderkit.html.HtmlGridRendererBase.encodeEnd(HtmlGridRendererBase.java:85)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:331)
...snip...
Caused by: java.lang.IllegalArgumentException: setAttribute: Non-serializable attribute
at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1249)
at org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:129)
at org.apache.myfaces.context.servlet.SessionMap.setAttribute(SessionMap.java:50)
at org.apache.myfaces.context.servlet.AbstractAttributeMap.put(AbstractAttributeMap.java:104)
...snip...
Feb 9, 2006 7:39:03 AM org.apache.catalina.core.ApplicationDispatcher invoke
SEVERE: Servlet.service() for servlet jsp threw exception
javax.faces.el.EvaluationException: Cannot get value for expression '#{!menu.userLoggedIn}'
at org.apache.myfaces.el.ValueBindingImpl.getValue(ValueBindingImpl.java:397)
at javax.faces.component.UIComponentBase.isRendered(UIComponentBase.java:822)
at org.apache.myfaces.renderkit.html.HtmlGridRendererBase.renderChildren(HtmlGridRendererBase.java:176)
at org.apache.myfaces.renderkit.html.HtmlGridRendererBase.encodeEnd(HtmlGridRendererBase.java:85)
at javax.faces.component.UIComponentBase.encodeEnd(UIComponentBase.java:331)
...snip...
Caused by: java.lang.IllegalArgumentException: setAttribute: Non-serializable attribute
at org.apache.catalina.session.StandardSession.setAttribute(StandardSession.java:1249)
at org.apache.catalina.session.StandardSessionFacade.setAttribute(StandardSessionFacade.java:129)
at org.apache.myfaces.context.servlet.SessionMap.setAttribute(SessionMap.java:50)
at org.apache.myfaces.context.servlet.AbstractAttributeMap.put(AbstractAttributeMap.java:104)
at org.apache.myfaces.el.VariableResolverImpl$13.put(VariableResolverImpl.java:192)
at org.apache.myfaces.el.VariableResolverImpl.resolveVariable(VariableResolverImpl.java:328)
...snip...
The other interesting thing that I noticed is how far along the hibernate annotations are, I had no real problems with my little sample app, of course your millage might varry. Next up I'd like to convert the app to use Cayenne and then get it to deploy on Geronimo... Ah if only I could give up sleep :-)
Anyway here is the screen flow captured in a notation that is easy to do with Omni Graffle. And here is the domain model. And finally for you that are sick of docs and just want to look at the code you can download it here. And finally a pointer to the way back preso here. The code for the example is licensed with the ASF 2.0 license so you are fee to do with it what you will as long as you don't sue me...
Have fun, and any feed back would be greatly appreciated.

