Showing posts with label Hibernate. Show all posts
Showing posts with label Hibernate. Show all posts

Thursday, September 03, 2009

How to Debug Hibernate Mapping Problems

If you are using Hibernate in Tomcat with XML configuration files (rather than annotations) you probably have had an instance where there was a problem with a mapping file and Tomcat will not start correctly. The catalina log will show the mappings being loaded over and over again. Since there is no clear order to what will be loaded next, it's not possible to tell which file is causing the issue.

What you can do on a UNIX system is install strace. strace will show you all the system calls being executed by a process. You can attach strace to a running process and log output and then inspect which file Tomcat loaded (if you're lucky, there will be a SEGFAULT or some other problem). The mapping files be loaded over and over again, so you just need to find where they start to loop and the last mapping is the one that is causing the problem. To do that, you can find the first mapping file that is loaded and simply search in the log for the next occurrence. Scroll up and you'll find the culprit.

Step by step:
  1. Start Tomcat
  2. Press CTRL-Z to suspend Tomcat
  3. ps -ef | grep juli to find all instances of Tomcat; note down the PID (usually the first of two similar, adjacent numbers)
  4. Execute "bg 1" to resume execution of Tomcat
  5. Execute "strace -fF -p YOUR_PID_HERE &> strace.log" to trace Tomcat
That's it... good luck!

Thursday, July 30, 2009

Using Named Queries

Named queries make it easy to reuse SQL queries in JPA Entity Beans & Controllers and they are also more readable than inline SQL. I'm not sure, but my guess is they probably run faster too.

There are two steps.

1. Add Named Queries as a comma delimited list before your Entity bean's class definition, like so (Remember that the queries are in QL, not SQL. It's SQL like syntax, but you're manipulating the Java objects, not the underlying SQL, so name your "tables" and "columns" appropriately):
@Entity
@Table(name = "MY_TABLE", catalog = "", schema = "")
@NamedQueries({
@NamedQuery(name = "SchedJob.findAll", query = "SELECT s FROM SchedJob s"),
...
)})
public class MyObject implements Serializable {
...


2. Use the named query in your controller by calling createNamedQuery on your entity manager.
    public List findByText(String text) {
EntityManager em = getEntityManager();
try {
Query q = em.createNamedQuery("MyObject.findByText");
q.setParameter("text", text);
return q.getResultList();
} finally {
em.close();
}
}

You can also return a single result and some other things (Google for the Javadocs).

A more compact format is:
Teachers teacher = (Teachers) 
em.createNamedQuery("Teachers.findByGName").setParameter("gName",
gNameString).getSingleResult();

or
List teachers = (Teachers) 
em.createNamedQuery("Teachers.findByGName").setParameter("gName",
gNameString).getResultList();

Labels

Blog Archive

Contributors