Using an EntityManagerFactory with JPA, Hibernate and Wicket

Nico Heid's picture

If you read the previous article "@OneToMany Relationship with Java, Hibernate and Annotations" you might have noticed some
imperfections in the persistence layer. On the code side we have been
lazy by just using FetchType.EAGER. This of course puts extra stress on
the database, because in our example, for each BlogPost all Comments are
fetched, even though they might not be displayed.


Maybe you played around with the example
version 0.1.1(download tarball).
You might have noticed that if you switch to FetchType.LAZY you will
most likely get a no session or session was closed on certain operations.


Let's take a closer look on where we did get our Session from

 

  1. // in BlogPostDAO
  2. Session session = HibernateUtil.getSession();
  3.  
  4. <java>
  5. // in HibernateUtil
  6. public class HibernateUtil {
  7.  
  8.     private static final SessionFactory sessionFactory;
  9.     static {
  10.         try {
  11.             AnnotationConfiguration configuration = new AnnotationConfiguration();
  12.             configuration.addAnnotatedClass(BlogPost.class);
  13.             configuration.addAnnotatedClass(Comment.class);
  14.             sessionFactory = configuration.buildSessionFactory();
  15.  
  16.         } catch (Throwable ex) {
  17.             // Log exception!
  18.             throw new ExceptionInInitializerError(ex);
  19.         }
  20.     }
  21.  
  22.     public static Session getSession() throws HibernateException {
  23.         return sessionFactory.openSession();
  24.     }
  25.  
  26. }





As you can see, we open a new Session each time we request a Session via
getSession(). Each DAO file did get its own Session which it closes
after using. So operating on a lazy initialized class member does give a
no session or session was
closed

error. Because by the time you want to display the comments, the Session
is already closed. Hibernate did use proxy objects (read more on
Proxy Visor Pattern
) instead of the real comments. Now the first read access hits the
Comments member, and Hibernate needs to load the content from the
database, but the Session is already closed.



Now is the time to take the design up a notch by introducing Spring 3
into the project. We're especially looking at the
LocalContainerEntityManagerFactoryBean
. We use it to set up a JPA EntityManagerFactory and pass it into our
persistence layer using dependency injecton.


There is a really good example on how to do this with Wicket, it's
called powerblog and it can be found here:
tutorialWicketSpringJPAHibernateCore


As you can see I updated yawblog using a setup similar powerblog's. You find the
yawblog
source on github
.


If you look into YawJPAImpl you will recognize that the EntityManager is used to handle all
database operations. The spring context is set up, that the YawJPAImpl
is a bean available to the Wicket application. Whenever you need access to the persistence layer, you can get the bean
using the
@SpringBean
annotation.


  1. public class BasePage extends WebPage {
  2.     @SpringBean(name = "yawData")
  3.     protected YawJPAImpl yawData;
  4.  
  5.     @Override
  6.     protected void onBeforeRender() {
  7.         super.onBeforeRender();
  8.         Application.get().getMarkupSettings().setStripWicketTags(true);
  9.     }
  10.  
  11.     public BasePage() {
  12.         add(new Label("navigation_panel", yawData.getPage("navigationPanel").getContent()).setEscapeModelStrings(false));
  13.         add(new Label("right_sidebar", yawData.getPage("rightSidebar").getContent()).setEscapeModelStrings(false));
  14.         add(new Label("dashboard", yawData.getPage("dashboard").getContent()).setEscapeModelStrings(false));
  15.         add(new Label("footer", yawData.getPage("footer").getContent()).setEscapeModelStrings(false));
  16.     }
  17. }



Now you can use the member yawData to access the persistence layer in
every page which extends BasePage.


Comments

@OneToMany Relationship with Java, Hibernate and Annotations's picture

[...] There is a follow up here: Using an EntityManagerFactory with JPA, Hibernate and Wicket which fixes some design [...]