diff options
Diffstat (limited to 'documentation/jpacontainer/jpacontainer-hibernate.asciidoc')
-rw-r--r-- | documentation/jpacontainer/jpacontainer-hibernate.asciidoc | 180 |
1 files changed, 0 insertions, 180 deletions
diff --git a/documentation/jpacontainer/jpacontainer-hibernate.asciidoc b/documentation/jpacontainer/jpacontainer-hibernate.asciidoc deleted file mode 100644 index de7f26d9a0..0000000000 --- a/documentation/jpacontainer/jpacontainer-hibernate.asciidoc +++ /dev/null @@ -1,180 +0,0 @@ ---- -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"] ----- -<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)) ----- - - - - |