--- 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 entityManagerThreadLocal = new ThreadLocal(); @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"] ---- <filter> <filter-name>**LazyHibernateServletFilter**</filter-name> <filter-class>**com.example.LazyHibernateServletFilter**</filter-class> </filter> <filter-mapping> <filter-name>**LazyHibernateServletFilter**</filter-name> <url-pattern>**/++*++**</url-pattern> </filter-mapping> ---- 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)) ----