<?xml version="1.0" encoding="UTF-8"?>
<rss version="2.0"
	xmlns:content="http://purl.org/rss/1.0/modules/content/"
	xmlns:wfw="http://wellformedweb.org/CommentAPI/"
	xmlns:dc="http://purl.org/dc/elements/1.1/"
	xmlns:atom="http://www.w3.org/2005/Atom"
	xmlns:sy="http://purl.org/rss/1.0/modules/syndication/"
	xmlns:slash="http://purl.org/rss/1.0/modules/slash/"
	>

<channel>
	<title>Tales From The Cloud &#187; jpa</title>
	<atom:link href="http://blog.newsplore.com/tag/jpa/feed" rel="self" type="application/rss+xml" />
	<link>http://blog.newsplore.com</link>
	<description>Everything beta</description>
	<lastBuildDate>Tue, 07 Sep 2010 10:40:06 +0000</lastBuildDate>
	<language>en</language>
	<sy:updatePeriod>hourly</sy:updatePeriod>
	<sy:updateFrequency>1</sy:updateFrequency>
	<generator>http://wordpress.org/?v=3.0.1</generator>
		<item>
		<title>Evaluating EclipseLink 1.1</title>
		<link>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11</link>
		<comments>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11#comments</comments>
		<pubDate>Sun, 22 Mar 2009 00:34:53 +0000</pubDate>
		<dc:creator>Florin</dc:creator>
				<category><![CDATA[java]]></category>
		<category><![CDATA[opinions]]></category>
		<category><![CDATA[software]]></category>
		<category><![CDATA[spring]]></category>
		<category><![CDATA[EclipseLink]]></category>
		<category><![CDATA[hibernate]]></category>
		<category><![CDATA[JEE]]></category>
		<category><![CDATA[jpa]]></category>

		<guid isPermaLink="false">http://blog.newsplore.com/?p=981</guid>
		<description><![CDATA[As I&#8217;m using the ubiquitous Hibernate 3.3 as the JPA 1.0 provider for Spincloud, I decided to try out another one. I had tried OpenJPA (spawned from Kodo JDO) when they only supported build-time bytecode enhancement and it was a pain to make it work. It worked all right but boy what a pain. There&#8217;s [...]]]></description>
			<content:encoded><![CDATA[<div class="tweetmeme_button" style="padding-right:0;margin-top:3px"><a href="http://api.tweetmeme.com/share?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F21%2Fevaluating-eclipselink-11"><img src="http://api.tweetmeme.com/imagebutton.gif?url=http%3A%2F%2Fblog.newsplore.com%2F2009%2F03%2F21%2Fevaluating-eclipselink-11" height="61" width="51" /></a></div><p align='justify'>As I&#8217;m using the ubiquitous Hibernate 3.3 as the JPA 1.0 provider for <a href="http://spincloud.com">Spincloud</a>, I decided to try out another one. I had tried <a href="http://openjpa.apache.org/">OpenJPA</a> (spawned from Kodo JDO) when they only supported <a href="http://people.apache.org/~mprudhom/openjpa/site/openjpa-project/manual/ref_guide_pc_enhance.html#ref_guide_pc_enhance_build">build-time bytecode enhancement</a> and it was a pain to make it work. It worked all right but boy what a pain. There&#8217;s  now an <a href="http://people.apache.org/~mprudhom/openjpa/site/openjpa-project/manual/ref_guide_pc_enhance.html#ref_guide_pc_enhance_runtime">agent</a> to provide on-the-fly enhancement but I&#8217;ll take transparent enhancement anytime.<br />
I&#8217;ve heard about EclipseLink before. The project started when Oracle donated the respectable <a href="http://www.oracle.com/technology/tech/java/newsletter/articles/toplink/history_of_toplink.html">TopLink project</a> to the Eclipse foundation. If the solid reputation behind TopLink was a good enough argument for me to try it, the announcement that <a href="http://eclipselink.blogspot.com/2008/03/eclipselink-to-provide-jpa-20-reference.html">it will be the JPA 2.0 reference implementation</a> convinced me that I should try it out.<br />
My goal is to evaluate if EclipseLink is production-ready. I&#8217;m applying a complex set of evaluation criteria (joking): if it can run Spincloud then it is (I was inspired by Seifer&#8217;s <a href="http://www.infoq.com/presentations/seifer-ruby-vm-comparison">interview on Infoq</a> about Ruby VMs; when asked what was the criteria for qualifying if a Ruby VM is production ready, he answered: if it runs Rails).</p>
<p>I have the following JPA requirements:<br />
- column mappings, one-to-one, one-to-many<br />
- supports BLOB fields<br />
- supports NamedQueries and NamedNativeQueries<br />
- support for object cache and query cache<br />
- deployment/operational nice to have: ease of maintaining compatibility with both  EclipseLink and Hibernate in the source code and runtime. Ideally I should plug-in any JPA provider without changing a single line of code. This was not attainable as I&#8217;ll explain below.</p>
<p>I started by downloading the binaries</a>. I&#8217;m using Maven to bring the jars so I&#8217;ve followed the instructions <a href="http://wiki.eclipse.org/EclipseLink/Maven">here</a>. I only changed the version since I wanted to use v1.1.0:</p>
<pre>
  &lt;dependency&gt;
    &lt;groupId&gt;org.eclipse.persistence&lt;/groupId&gt;
    &lt;artifactId&gt;eclipselink&lt;/artifactId&gt;
    &lt;version&gt;1.1.0&lt;/version&gt;
    &lt;scope&gt;provided&lt;/scope&gt;
  &lt;/dependency&gt;
</pre>
<p>There&#8217;s a single jar file called eclipselink-1.1.0.jar downloaded which is a nice change from the multitude of Hibernate jars I was accustomed with.<br />
<span id="more-981"></span><br />
Next, I created a new persistence.xml file since I didn&#8217;t know how different it would be from the one tied to Hibernate. Initially I just changed the JPA provider to:</p>
<pre>
  &lt;provider&gt;org.eclipse.persistence.jpa.PersistenceProvider&lt;/provider&gt;
</pre>
<p>as the documentation stated.<br />
Then I had a look at my current NamedQueries and NamedNativeQueries that looked like this:</p>
<pre>
@org.hibernate.annotations.NamedQueries({
	@org.hibernate.annotations.NamedQuery(name="findStationByPK",
	        query="select station from Station station where station.id=:stationPK"
	        , cacheable=true, cacheRegion="weatherStationsRegion"),
...
</pre>
<p>and I recalled that I did this in order to make use of Hibernate&#8217;s Query cache facility, alas a non-standard way of cache enablement (not until JPA 2.0 anyway). I had to put query caching to rest and switched all my Named*Queries to standard JPA:</p>
<pre>
@javax.persistence.NamedQueries({
	@javax.persistence.NamedQuery(name="findStationByPK",
	        query="select station from Station where id=:stationPK"),
...
</pre>
<p> I&#8217;m not using the integration unit tests I have due to the issues I had with the <a href="http://static.springframework.org/spring/docs/2.0.x/reference/testing.html#integration-testing">Spring integration test framework</a> I&#8217;m using after switching to Spring 3.0 so I&#8217;m using ad-hoc testing for now.  After rebuilding/deploying the project I didn&#8217;t notice any error on Tomcat start-up so I just tried the GUI, displaying the weather in a map area. I hit the first error:</p>
<pre>
Exception [EclipseLink-7060] (Eclipse Persistence Services - 1.1.0.r3639-SNAPSHOT):
org.eclipse.persistence.exceptions.ValidationException
Exception Description: Cannot acquire data source [java:comp/env/ds/MeteoDS].
Internal Exception: javax.naming.NamingException: This context must be accessed
throughout a java: URL
</pre>
<p>I dug through the documentation (what&#8217;s with this documentation and what does <a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Limitations_to_JPA">&#8220;No dynamic weaving (instrumentation) &#8211; static weaving of entities is still available via EclipseLink&#8221;</a> means, why JPAEclipseLinkSessionCustomizer example is broken and finally why use teh deprecated SessionCustomizer?) and found that I have to use a <a href="http://wiki.eclipse.org/EclipseLink/Examples/JPA/Tomcat_Web_Tutorial#Session_Customizer">session customizer</a> to make it work in Tomcat. I didn&#8217;t like this one bit (it just works in Hibernate) but I followed the instructions and EclipseLink could establish the connection with the Tomcat-configured data source as expected. This was the first duly noted turn-off.<br />
I redeployed and browsed the weather map just to hit another problem:</p>
<pre>
  Exception Description: Syntax error parsing the query [findStationByPK:
    select station from   Station where id=:stationPK], line 1, column 28:
    syntax error at [where].
 Internal Exception: MismatchedTokenException(65!=66)
</pre>
<p>Hmm, no compile-time JPA query check. Not good. I checked the JPA query, it was:</p>
<pre>
  @javax.persistence.NamedQuery(name="findStationByPK",
       query="select station from Station where id=:stationPK"),
...
</pre>
<p>which looked OK but looking closely I realized that it was not. The correct syntax is (notice the <b>station.</b> indirection:</p>
<pre>
@javax.persistence.NamedQueries({
	@javax.persistence.NamedQuery(name="findStationByPK",
	        query="select station from Station <b>station</b> where <b>station</b>.id=:stationPK"),
	@javax.persistence.NamedQuery(name="findByStationId",
...
</pre>
<p>Hibernate was happy with the &#8220;non-standard&#8221; syntax while EclipseLink is not. No big deal, it wasn&#8217;t in many places anyway. I scanned all my queries and fixed them. Redeployed and hit this:</p>
<pre>
  Exception Description: Syntax error parsing the query [findByStationId: from
    Station station where station.stationId=:stationId], line 1, column 0:
    unexpected token [from].
</pre>
<p>My JPA query is:</p>
<pre>
	@javax.persistence.NamedQuery(name="findByStationId",
	        query="from Station station where station.stationId=:stationId")
</pre>
<p>Again a Hibernate artifact. H3 supports the convenience of using queries that start with &#8220;from entity&#8230;&#8221; if they return entities (single or lists). The fix was simply to add &#8220;select station&#8221; in front of the JPA QL:</p>
<pre>
	@javax.persistence.NamedQuery(name="findByStationId",
	        query="<b>select station</b> from Station station where
                station.stationId=:stationId")
</pre>
<p>Not a biggie either, standard is better and Hibernate can parse this kind of query. Again, rebuilt/redeployed and queried the map again. This time the error was this:</p>
<pre>
[EL Warning]: 2009-03-21 19:02:42.135--UnitOfWork(2001070194)--Exception [EclipseLink-4002]
(Eclipse Persistence Services -
 1.1.0.r3639-SNAPSHOT): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException:
You have an error in your SQL syntax; check
the manual that corresponds to your MySQL server version for the right syntax to use
near ':area) , LOCATION) and obs_time
&gt; :minSynopDateToConsiderStr UNION select distin' at line 1
Error Code: 1064
Call: <b>select distinct STATION_FK as STATION_IDENTIFIER, LOCATION,
obs_time as REPORT_TIME  from SYNOP where Contains(GeomFromText(:area) , LOCATION) and
obs_time &gt; :minSynopDateToConsiderStr UNION
select distinct STATION_FK as STATION_IDENTIFIER,
LOCATION, REPORT_TIME as REPORT_TIME from METAR where
Contains(GeomFromText(:area) , LOCATION) and REPORT_TIME &gt; :minMetarDateToConsiderStr</b>
</pre>
<p>I couldn&#8217;t find anything at first in the documentation (getting really pissed at the documentation style, can&#8217;t find anything useful) but I finally found <a href="//wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#Using_Named_Parameters_in_a_Native_Query">this</a>:</p>
<pre>
Support for the EclipseLink # convention is helpful if you are already familiar with
EclipseLink queries or if you are migrating EclipseLink queries to a JPA application.
</pre>
<p>I&#8217;m not &#8220;already familiar with EclipseLink queries&#8221; and no, it&#8217;s not helpful. So now I have to use #area instead of :area named parameter. This is really smart. Why in the world would one want to change the column with sharp? I&#8217;m starting to suspect clumsiness or plain careless coding. I still want to maintain Hibernate/EclipseLink pluggability so I have no choice but creating a static class that holds all NamedNativeQueries and parametrizes the named parameter prefix:</p>
<pre>
class NativeQueries {
public final static String WEATHER_SNAPSHOT_IN_AREA_NATIVE_QUERY ="select distinct
STATION_FK as STATION_IDENTIFIER, LOCATION, obs_time as REPORT_TIME from SYNOP where
Contains (GeomFromText(<font color="red">@named-param-prefix@</font>area) " +
 ", LOCATION) and obs_time &gt; <font color="red">@named-param-prefix@</font>minSynopDateToConsiderStr UNION " +
"select distinct STATION_FK as STATION_IDENTIFIER, LOCATION, REPORT_TIME
as REPORT_TIME from METAR where Contains(GeomFromText(<font color="red">@named-param-prefix@</font>area) " +
", LOCATION) and REPORT_TIME &gt; <font color="red">@named-param-prefix@</font>minMetarDateToConsiderStr";
...
}
</pre>
<p>Then I have to use ant to perform a pre-compilation task that replaces <font color="red">@named-param-prefix@</font> with either : or #. This really got the best of me as I&#8217;ve hit a Java compilation quirk too: you have to delete all classes that rely on the NativeQueries class since they will not recompile if the values of the <b>public static final String</b> values change; you have to delete all .class files and force a full compilation for them.<br />
After I did this build change it all started working. Victory at last. Or was it? Well, no; I still have to add query caching as I heavily use spatial queries to fetch area weather (activated every time the map is dragged/zoomed). There&#8217;s the <a href="http://wiki.eclipse.org/Using_EclipseLink_JPA_Extensions_(ELUG)#Using_EclipseLink_JPA_Extensions_for_Entity_Caching">@Cache</a> but it&#8217;s for entity caching which is good but what I also need is query caching à la Hibernate: </p>
<pre>
 @org.hibernate.annotations.NamedQuery(name="qName", query="&lt;query&gt;",
    <font color="red">cacheable=true, cacheRegion="some-cache-region"</font>)
</pre>
<p align='justify'>
After another round of thorough search of the documentation I <a href="http://wiki.eclipse.org/Using_Advanced_Query_API_%28ELUG%29#Using_Queries_and_the_Cache">found what I needed</a> but it wasn&#8217;t what I expected. EclipseLink doesn&#8217;t support annotation-level query cache configuration. Instead you have to code-in (or use AOP to) cache writes after the queries are executed, via its ReadQuery class.<br />
Needless to say I didn&#8217;t do it. I gave up on it right there.<br />
On a whole this felt a lot like my (undocumented) evaluation I did over a year ago with OpenJPA (no dice too). Poor documentation (worse than EL&#8217;s) and lack of (then) runtime weaving made it a nightmare to deploy. I haven&#8217;t tried it ever since.</p>
<p>Prognosis: negative</p>
<p>This is really a shame, EclipseLink seems to be quite fast and has a footprint similar to Hibernate but:<br />
- the documentation is awful. Guys, look at Hibernate and follow their lead. I badly need a single page HTML up-to-date documentation that I can freely browse. I can find almost anything in a matter of seconds using Hibernate&#8217;s single page HTML doc and Ctrl-F. I feel so strongly about this, I&#8217;d make an addition to the <a href="http://manifesto.softwarecraftsmanship.org/">Software Craftsmanship Manifesto:</a> <b>&#8220;Maintain top-notch documentation&#8221;</b>. Spring and Hibernate projects got it right and this is one of the secrets of their success. Take note.<br />
- Use : (column) for named parameters in NamedNativeQuery; it is consistent with NamedQuery syntax (and hopefully standardized in JPA 2.0).<br />
- Use compile-time Named*Query syntax check. It adds a great deal to predictability.<br />
- Add the Session Customizer fix into of the base platform and make it transparent to the user. Nobody wants to write integration code to fix oddities of popular containers. &#8220;Out of the box&#8221; is valuable.<br />
- Work on a better query caching support or push hard for a JPA 2.0 beta since there&#8217;s standardized second-level caching.</p>
<p>Oh and guys, <a href="http://wiki.eclipse.org/Introduction_to_EclipseLink_Queries_(ELUG)">some</a> documentation pages don&#8217;t render properly on Safari, the TOCs overlap the content. Unacceptable.</p>
<p>Until then I&#8217;m sticking with Hibernate 3.3. It just works.</p>
<p class="fbconnect_share"><fb:share-button class="url" href="http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11" /></p>]]></content:encoded>
			<wfw:commentRss>http://blog.newsplore.com/2009/03/21/evaluating-eclipselink-11/feed</wfw:commentRss>
		<slash:comments>5</slash:comments>
		</item>
	</channel>
</rss>
