{"id":201,"date":"2010-05-23T22:14:16","date_gmt":"2010-05-23T20:14:16","guid":{"rendered":"http:\/\/touk.pl\/blog\/?p=201"},"modified":"2023-03-20T12:45:55","modified_gmt":"2023-03-20T11:45:55","slug":"hibernate-annotations-spring-transactions-in-osgi","status":"publish","type":"post","link":"https:\/\/touk.pl\/blog\/2010\/05\/23\/hibernate-annotations-spring-transactions-in-osgi\/","title":{"rendered":"Hibernate annotations + Spring transactions in OSGI"},"content":{"rendered":"<p>On our new project we decided to develop backend as services deployed on Servicemix 4.2. To make it easier for developers more familiar with &#8216;traditional&#8217; web applications based on spring+hibernate stack it should (at least partially) resemble such application. Therefore, we want to have following bundles:<\/p>\n<ul>\n<li>model &#8211;\u00a0 containing hibernate classes<\/li>\n<li>dao &#8211; implemented using hibernate template<\/li>\n<li>service &#8211; interfaces for bundles implementing webservices, also controlling transactions, validation and similar stuff<\/li>\n<\/ul>\n<p>So far, so good. Additional requirements are:<\/p>\n<ul>\n<li>hibernate is configured using annotations<\/li>\n<li>we use declarative transaction management with spring @Transactional annotation<\/li>\n<\/ul>\n<p>Now, the question is &#8211; how to achieve it in OSGI environment? There are some tutorials on the web, but I haven&#8217;t found anything about this particular configuration, so I want to share our solution &#8211; as it wasn&#8217;t as straightforward as one might expect.<\/p>\n<h3 id=\"hibernate-bundle\">Hibernate bundle<\/h3>\n<p>The very first problem was the structure of hibernate jars themselves. It turned out that simple<\/p>\n<p><code>wrap:mvn:org.hibernate:hibernate:3.3.1.GA<\/code><\/p>\n<p>is not enough when one wants to use annotations. The problem is that both hibernate-core, and hibernate-annotations are using same package, namely <code>org.hibernate.cfg<\/code>. This is pretty anti-OSGI design, as OSGI bundle can use package exported by exactly one bundle.<\/p>\n<p>The solution is of course pretty simple &#8211; we have to create our own bundle, which embeds both hibernate jars. This can be achieved with following maven-bundle-plugin configuration:<\/p>\n<pre class=\"brush:xml\">          \r\n\r\n    *;uses:=\"org.hibernate\";version=3.3.1.GA\r\n    !*\r\n    *;scope=compile|runtime;type=!pom;inline=true<\/pre>\n<p>Of course, you have to add hibernate dependencies to pom.<\/p>\n<h3 id=\"session-factory-and-transaction-management\">Session factory and transaction management<\/h3>\n<p>Servicemix has its own JTA TransactionManager, and at first I wanted to use it for managing our hibernate transactions. Unfortunatelly it turned to be somewhat tricky, so I decided to use simple solution, i.e. <code>org.springframework.orm.hibernate.HibernateTransactionManager<\/code>. It is declared in our dao bundle and exported as OSGI service:<\/p>\n<pre class=\"brush:xml\">\t\r\n\r\n    org.springframework.transaction.PlatformTransactionManager<\/pre>\n<p>Then, in service bundle we import it, and configure declarative transactions:<\/p>\n<pre class=\"brush:xml\"><\/pre>\n<p>So far, it doesn&#8217;t look much more complicated than in traditional, monolithic war application. But there is one more caveat:<\/p>\n<h3 id=\"org-hibernate-jdbc-connectionwrapper-is-not-visible-from-class-loader\">org.hibernate.jdbc.ConnectionWrapper is not visible from class loader<\/h3>\n<p>At first I thought it&#8217;s a matter of some misconfigured import\/export declarations in some of our bundles. However, after some googling it turned out that it&#8217;s <a href=\"http:\/\/opensource.atlassian.com\/projects\/hibernate\/browse\/HHH-3529\">Hibernate&#8217;s bug<\/a><\/p>\n<p>It is caused by using Thread context classloader when obtaining connection. It looks that the bug itself is already fixed, but we didn&#8217;t want to change to Hibernate 3.5 just because of that.<\/p>\n<p>It turns out that there is quire simple workaround &#8211; you just need to make Spring aspect that will set context classloader to proper one (i.e. bundle class loader) before opening hibernate session, and you&#8217;re done. But again, using Servicemix makes it slightly harded, as it turns out that using @AspectJ style poses some difficulties (see e.g. <a href=\"http:\/\/mail-archives.apache.org\/mod_mbox\/servicemix-users\/201004.mbox\/%3C2443D95470D8D8449B8CF1984400858701FB49CA@exchange2.corp.ebates.com%3E\">this thread<\/a>).<\/p>\n<p>But it turns out that there is pretty simple solution &#8211; use old, Spring 1.x-style aspects :). This requires a bit more boilerplate xml, but at least we got it working pretty quickly.<\/p>\n<p>The aspect class, setting proper classloader:<\/p>\n<pre class=\"brush:java\">public class AspectFix implements MethodInterceptor {\r\n\r\n    public Object invoke(MethodInvocation invocation) throws Throwable {\r\n        ClassLoader contextClassLoader = Thread.currentThread().getContextClassLoader();\r\n        Thread.currentThread().setContextClassLoader(getClass().getClassLoader());\r\n        try {\r\n            return invocation.proceed();\r\n        }\r\n            finally{ Thread.currentThread().setContextClassLoader(contextClassLoader);\r\n        }\r\n    }<\/pre>\n<p>The xml config:<\/p>\n<pre class=\"brush:xml\">\r\n\r\n      .*\r\n\r\n    *Service\r\n\r\n      fix<\/pre>\n<p>Final remark &#8211; now the service bundle has to import <strong>org.hibernate.jdbc<\/strong> to make it all work &#8211; as its classloader is used to initialize connection now.<\/p>\n<p>To sum up: this is definitely not the most elegant solution one can imagine- but it&#8217;s working.<\/p>\n","protected":false},"excerpt":{"rendered":"On our new project we decided to develop backend as services deployed on Servicemix 4.2. To make it&hellip;\n","protected":false},"author":4,"featured_media":0,"comment_status":"open","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[11],"tags":[43,44,42],"class_list":{"0":"post-201","1":"post","2":"type-post","3":"status-publish","4":"format-standard","6":"category-development-design","7":"tag-hibernate","8":"tag-osgi","9":"tag-spring-framework"},"_links":{"self":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/201","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/users\/4"}],"replies":[{"embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/comments?post=201"}],"version-history":[{"count":17,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/201\/revisions"}],"predecessor-version":[{"id":15345,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/posts\/201\/revisions\/15345"}],"wp:attachment":[{"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/media?parent=201"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/categories?post=201"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/touk.pl\/blog\/wp-json\/wp\/v2\/tags?post=201"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}