---
title: Using JPAContainer with Hibernate
order: 9
layout: page
---

[[jpacontainer.hibernate]]
= Using JPAContainer with Hibernate

Hibernate needs special handling in some cases.

[[jpacontainer.hibernate.lazyloading]]
== Lazy loading

In order for lazy loading to work automatically, an entity must be attached to
an entity manager. Unfortunately, Hibernate can not keep entity managers for
long without problems. To work around the problem, you need to use a special
lazy loading delegate for Hibernate.

JPAContainer entity providers handle lazy loading in delegates defined by the
[interfacename]#LazyLoadingDelegate# interface. The default implementation for
Hibernate is defined in [classname]#HibernateLazyLoadingDelegate#. You can
instantiate one and use it in an entity provider with
[methodname]#setLazyLoadingDelegate()#.

The default implementation works so that whenever a lazy property is accessed
through the Vaadin Property interface, the value is retrieved with a separate
(JPA Criteria API) query using the currently active entity manager. The value is
then manually attached to the entity instance, which is detached from the entity
manager. If this default implementation is not good enough, you may need to make
your own implementation.


ifdef::web[]
[[jpacontainer.hibernate.em-per-request]]
== The EntityManager-Per-Request pattern

One issue with Hibernate is that it is designed for short-lived sessions, but
the lifetime of an entity manager is normally roughly that of a user session.
The problem is that if an error occurs in a session or an entity manager, the
manager becomes unuseable. This causes big problems with long-lived sessions
that would work fine with EclipseLink.

The recommended solution is to use the __EntityManager-per-Request__ pattern. It
is highly recommended always when using Hibernate.

An entity manager can only be open during the request-response cycle of the
Vaadin servlet, so that one is created at the beginning of the request and
closed at the end.

[[jpacontainer.hibernate.em-per-request.provider]]
=== Storing an Entity Manager

You first need to implement an [interfacename]#EntityManagerProvider# that
returns a stored [interfacename]#EntityManager# with
[methodname]#getEntityManager()#. The entity manager must be stored in a
[classname]#ThreadLocal# variable.


----
public class LazyHibernateEntityManagerProvider
       implements EntityManagerProvider {
    private static ThreadLocal<EntityManager>
        entityManagerThreadLocal =
            new ThreadLocal<EntityManager>();

    @Override
    public EntityManager getEntityManager() {
        return entityManagerThreadLocal.get();
    }

    public static void setCurrentEntityManager(
                               EntityManager em) {
        entityManagerThreadLocal.set(em);
    }
}
----

You need to create and store the per-request instance at the beginning of each
request with [methodname]#setCurrentEntityManager()# and clear it at the end by
setting it as [literal]#++null++#.


[[jpacontainer.hibernate.em-per-request.provider]]
=== Creating Entity Managers in a Servlet Filter

You can create the entity managers for each request either by extending
[classname]#VaadinServlet# and overriding the [methodname]#service()# method or
by implementing a servlet filter. In the following, we describe how to implement
a servlet filter to do the task, but overriding the servlet could be even
easier.


----
public class LazyHibernateServletFilter
       implements Filter {

    private EntityManagerFactory entityManagerFactory;

    @Override
    public void init(FilterConfig filterConfig)
            throws ServletException {
        entityManagerFactory = Persistence
            .createEntityManagerFactory("lazyhibernate");
    }

    @Override
    public void doFilter(ServletRequest servletRequest,
                         ServletResponse servletResponse,
                         FilterChain filterChain)
            throws IOException, ServletException {
        try {
            // Create and set the entity manager
            LazyHibernateEntityManagerProvider
                .setCurrentEntityManager(
                    entityManagerFactory
                        .createEntityManager());

            // Handle the request
            filterChain.doFilter(servletRequest,
                                 servletResponse);
        } finally {
            // Reset the entity manager
            LazyHibernateEntityManagerProvider
                    .setCurrentEntityManager(null);
        }
    }

    @Override
    public void destroy() {
        entityManagerFactory = null;
    }
}
----

You need to define the servlet filter in the [filename]#web.xml# deployment
descriptor as follows:

[subs="normal"]
----
&lt;filter&gt;
    &lt;filter-name&gt;**LazyHibernateServletFilter**&lt;/filter-name&gt;
    &lt;filter-class&gt;**com.example.LazyHibernateServletFilter**&lt;/filter-class&gt;
&lt;/filter&gt;
&lt;filter-mapping&gt;
    &lt;filter-name&gt;**LazyHibernateServletFilter**&lt;/filter-name&gt;
    &lt;url-pattern&gt;**/++*++**&lt;/url-pattern&gt;
&lt;/filter-mapping&gt;
----
The [literal]#++url-pattern++# must match the pattern for your Vaadin servlet.


endif::web[]

[[jpacontainer.hibernate.joins]]
== Joins in Hibernate vs EclipseLink

EclipseLink supports implicit joins, while Hibernate requires explicit joins. In
SQL terms, an explicit join is a " [literal]#++FROM a INNER JOIN b ON a.bid =
b.id++#" expression, while an implicit join is done in a WHERE clause, such as:
" [literal]#++FROM a,b WHERE a.bid = b.id++#".

In a JPAContainer filter with EclipseLink, an implicit join would have form:


----
new Equal("skills.skill", s)
----

In Hibernate you would need to use [classname]#JoinFilter# for the explicit
join:


----
new JoinFilter("skills", new Equal("skill", s))
----




