Hibernate: Non object retrieval

Hibernate has significantly reduced the amount of time I’ve spent on the writing and maintaining SQL in the applications I’m working on. Because it exists to map data from Java classes to database tables and back, there aren’t alot of examples on the site if you need to get non object data out of the database (for instance if you’re doing reporting on the existing data). That’s not to say that it’s not possible! Given a Query object, call the list() method and then iterate over the resulting List. Calling the get() method on the list results in an array of Objects (which is analogous to a row returned from a resultset). Then you’ll just need to retrieve the appropriate element of the array given your SQL query (where the order of the items in your ‘SELECT ..’ SQL query determines the order in which the objects are returned in the Object[]).

// .. code to create a Query object
List list = q.list();
for (int i=0; i
If you're having trouble finding out the Java type of the element in a row, I've found Hibern8IDE to be an excellent help in running, testing and debugging Hibernate queries.

Struts & Java Tips: Issue #2

A couple weeks ago I wrote a short essay on some of the things that I ran into while working with Java and Jakarta Struts. Because I didn’t know what else to call it, I jokingly referred to it as Issue #1. Well, a month and a half later I think I have enough to write issue #2. I should probably call it something more general like ‘Java Web Development Tips’ or something, but why change now?

First, I thought I’d touch on some of the interesting things that I’ve run into while working in the presentation layer which in my case is JSP. This week I needed to create a search form that enabled end users to sort and filter results based on a number of parameters. Without showing 1000 lines of code, one of the challenges when doing a form like this is maintaining the form state when doing filtering and sorting (because not all the fields are sortable and not all can be filtered) and the most common solution is to use hidden form fields. Struts includes a <html:hidden> tag that will automatically maintain state for you form, but it requires that you know all the names of all the fields up front when you’re writing your form. If you decide to add a sortable or filterable property later, you’d need to hardcode another hidden form field. Instead, I chose to use the JSTL forEach tag and the special ‘param’ scope to programatically create my hidden form fields:

<c:forEach var="p" items="${param}">
  <input type="hidden" name="${p.key}" value="${p.value}">
</c:forEach>

The non-intuitive part of this code in my mind is the param ‘scope’, which (if you mess around with it a bit) is a HashMap derived from the getParameterMap() method of the ServletRequest interface. The forEach tag iterates over each parameter, which results in a Map.Entry; the Map.Entry provides JavaBean style accessors for key and value, which I can then use to create the hidden form fields.

The Action class that backs the search form uses an ActionForm to collect the data and then copies the data from the ActionForm bean to a bean made specifically for use with the search DAO. That code looks something like this:

public ActionForward execute(ActionMapping m, ActionForm f, HttpServletRequest req, HttpServletResponse res)
throws Exception {
...
// get the data posted from the form
SearchOrdersForm input = (SearchOrdersForm)f;
// bean coupled w/ the search DAO
ManagerSearchParams sp = new ManagerSearchParams();
// copy the properties from the form to the searchparams bean
// using the BeanUtils class
BeanUtils.copyProperties(sp, input);
// perform the search (in this case we're looking for orders
Collection orders = OrderDAO.findOrders(sp);
// push the collection to the jsp
request.setAttribute("orders", orders);

I’m not sure if there is a pattern in this or not, but the coupling of the ManagerSearchParams bean with the OrderDAO in the above example turned out (at least so far) to be very useful. Another part of the application required that I retrieve orders from persistent storage (in this case Hibernate & SQL Server) by date (ie: I needed to find all orders between date1 and date2). Instead of writing a new method on the DAO (ie: OrderDAO.searchbyDate()), the ManagerSearchParams bean already had start & end date properties. I simply created a new instance of the ManagerSearchParams bean, populated the startdate and enddate properties, and then fired the findOrders() method on the OrderDAO class.

Hibernate: Communication link failure: java.io.IOException

I recently launched a new site based on Struts, Hibernate and MySQL and immediately ran into a weird issue where Hibernate lost the ability to make database connections after a long period of inactivity. For the record, the stack trace is below:

java.sql.SQLException: Communication link failure: java.io.IOException
  at org.gjt.mm.mysql.MysqlIO.sendCommand(Unknown Source)
  at org.gjt.mm.mysql.MysqlIO.sqlQueryDirect(Unknown Source)
  at org.gjt.mm.mysql.Connection.execSQL(Unknown Source)
  at org.gjt.mm.mysql.PreparedStatement.executeQuery(Unknown Source)
  at net.sf.hibernate.impl.BatcherImpl.getResultSet(BatcherImpl.java:83)
  at net.sf.hibernate.loader.Loader.getResultSet(Loader.java:794)
  at net.sf.hibernate.hql.QueryTranslator.iterate(QueryTranslator.java:846)
  at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1540)
  at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1513)
  at net.sf.hibernate.impl.SessionImpl.iterate(SessionImpl.java:1505)

Looks like there are other people having the same problem, the first suggestion was to use the Thread Local Session pattern, which I already had in place. The solution was to add the following properties to my hibernate.cfg.xml:

<property name="connection.autoReconnect">true</property>
<property name="connection.autoReconnectForPools">true</property>
<property name="connection.is-connection-validation-required">true</property>

which I believe are specific to MySQL, but as far as I can tell, aren’t documented anywhere on the Hibernate site (or should they be documented on the MySQL JDBC driver site?)

For what it’s worth, Hibernate is a dream come true. I don’t like writing create, update, and delete SQL statements and I’ve found that the software I’ve written is much easier to manage and troubleshoot. If you haven’t played with it yet, check it out now.

ASP.NET: Data-binding array of hashtables

Spent this morning in ASP.NET land working on a small modification in which I needed to data bind an array of hashtables to an <asp:repeater>. Looks like some other ASP.NETers had the same problem, but the ‘solutions’ they offered didn’t seem to solve the errors I was getting. First, in the code behind, I had something like this in the code behind:

public Repeater events = new Repeater();
private ArrayList aEvents = new ArrayList();
public void Page_Load(Object sender, EventArgs e) {
  Hashtable event1 = new Hashtable();
  event1.Add("name", "name of event 1");
  event1.Add("date", "5/31/2004");
  Hashtable event2 = new Hashtable();
  event2.Add("name", "name of event 2");
  event2.Add("date", "06/20/2004");
  aEvents.Add(event1);
  aEvents.Add(event2);
  events.DataSource = aEvents;
  events.DataBind();
}

and then a standard repeater tag in my ASP.NET code:

<asp:repeater id="events" runat="server">
  <ItemTemplate>
  Name:<%# DataBinder.Eval(Container.DataItem,"name") %>
  Date:<%# DataBinder.Eval(Container.DataItem,"date") %>
  </ItemTemplate>
</asp:repeater>

The first error I got was DataBinder.Eval: 'System.Collections.Hashtable' does not contain a property with the name name., which means that the DataBinder uses reflection to find a property called ‘name’ on the current object in the iteration. This is a problem because obviously a hashtable doesn’t have a public property for ‘name’, it only has an associate array of values. The workaround, although I don’t know why this works, is to wrap the keys in a brackets:

Name:<%# DataBinder.Eval(Container.DataItem,"[name]") %>
Date:<%# DataBinder.Eval(Container.DataItem,"[date]") %>

Using brackets lets you use an array of hashtables as a datasource. Since this works, it might be helpful to add it to the Data Binding Expression Syntax guide on MSDN.

JavaServer Faces notes from NEJUG meeting

Just got back from the April NEJUG meeting on JavaServer Faces, which didn’t go so smoothly. The projector lamp went out about 10 minutes into the presentation, which left David Geary with no access to his slides for about 1.5 hours. He gracefully answered questions instead of going through his presentation; following are excerpts of the questions & answers I found intriguing. Hopefully he’ll post his slides, although the OnJava.com newsletter mentioned that JSF is *the* hot topic for the next couple months so I’m sure there is going to be apt coverage elsewhere.

· David was one of the original developers of Tiles, which was highlighted in the Struts in Action book I’ve read. It didn’t originally float my boat, but I should go back and look into it a bit more. On Oreilly: Programming Jakarta Struts: Using Tiles, Part 1, Part 2, Part 3, Part 4.

· 1 sentence summary of JSF: It’s Struts++ with an event model and components.

· On the record Sun will say that JSF doesn’t replace Struts, off the record it does.

· Also off the record, David mentioned that JSF might be (or is) the most expensive JSR ever.

· Lots of people were curious about how closely tied JSF was to JSP. The short answer is that it’s not, David mentioned that you simply need to ‘… create a new renderer..’ for whatever platform you are targeting. He mentioned multiple times that JSF is platform independent and that you could output to XUL, Swing or Midlets. Which makes me wonder how hard it would be to write a JSF application that outputs to Flex or Laszlo. Swing & Midlets though? I could be wrong, but I think what it actually does it create *data* that these platforms can then use. I don’t think you can create an application in JSF and then write a J2ME renderer that creates a jar file that you can deploy to a phone. Tell me if I’m wrong on that though, because it would be remarkable otherwise.

· Couple questions about the similarities between Webforms & ASP.NET. Some differences I picked up:

a) the tags and UI components aren’t browser aware, they don’t target a specific browser platform, which is different from ASP.NET (which will output different HTML depending on which browser is requesting data).

b) by default form data is persisted to session scope (is this really true?) although I don’t see how this is an improvement over Struts (which has form persistence already if you use the Struts <html:form> tags)

· Question re: the complexity of JSF: easier or harder to learn than Struts? David replied that he thought that newbies to each would take longer to learn JSF. Struts users should have an easier time learning how to use it.

· Question re: migrating from Struts to JSF: Take a look at the document Craig McClanahan put together here, Struts-Faces integration library

· Question re: Tapestry & WebWork: Both were definitely looked at during the JSR process, turns out the Tapestry guy is local to Boston.

· JSF supports 2 types of events: action events (which are fired onclick of a button or a link) and change events (which are fired when the value of an input component changes). Both require a round trip to the server, change events require the user to click on a submit button OR the developer to write a JavaScript onchange event handler to then fire the form submission process. This is different than ASP.NET, where you can declare onchange events in your ASP.NET tags and the corresponding JavaScript is automatically generated for you. Whether this is good or bad depends on how much you like the generated code, but it definitely makes it easier for people who don’t know anything about JavaScript).

· Question re: debugging: is it easier than Struts? No.

· David mentioned a couple times that he thought that Tomcat sucked and that he really likes Resin. Note to self: check out Resin

· The WebSphereâ„¢ Boston Users Group will be doing a presentation entitled “WSAD, JSF, and More” on April 29th. More information here.

That’s it for now.

Update 04/15/2004: The presentation files are now available on the NEJUG site.

Upgrading from Tomcat 4.x to 5.0.19: java.lang.IllegalStateException

Seems like this new ‘feature’ of Tomcat 5 is buried in Google, bringing it to the top for anyone interested. If you port a servlet from Tomcat 4.x to Tomcat 5 and you use (pseudo) code like this:

public void doPost(HttpServletRequest req,HttpServletResponse res) {
   // some sort of logic
  if (something) {
   forward("/somewhere", req, res);
  } else {
   // do this
  }
   // continue on with the page
}

public void forward(String url, HttpServletRequest req, HttpServletResponse res)
throws IOException, ServletException {
  RequestDispatcher rd = req.getRequestDispatcher(url);
  rd.forward(req, res);
}

you’ll find that the servlet will throw a java.lang.IllegalStateException with the message: Cannot forward after response has been committed. This condition is easily fixed by adding a ‘return’ statement after you call the forward method. So instead, you’d have this:

  if (something) {
   forward("/somewhere", req, res);
   return;
  } else {
   // do this
  }
   // continue on with the page

I bet this one catches alot of people coming from a scripting background where it’s fine and dandy to do a response.redirect() (ASP) or a <cflocation> and then continue on as if nothing had happened.

Read it on jakarta.apache.org here.