Intro
Recently I joined a project working with JEE 5 and Sun Application Server a.k.a. Glassfish. The default object-relational mapping solution in Glassfish is TopLink. More spefically TopLink® Essentials (sorry, almost forgot the ®), as Oracle calls it "the official open source reference implementation". I assume they are trying to win back some market share from Hibernate.
Although by reputation a proper framework I never took the time to work with TopLink because is was closed source (and cost mon€y). Now that it opened up I decided to give it a go. And fortunately (and to be honest as expected) Spring delivers an excellent integration.
Setup
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"> <property name="url" value="xxx" /> <property name="driverClassName" value="xxx" /> <property name="username" value="xxx" /> <property name="password" value="xxx" /> </bean> <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> <property name="dataSource" ref="dataSource" /> <property name="jpaVendorAdapter"> <bean class="org.springframework.orm.jpa.vendor.TopLinkJpaVendorAdapter"> <property name="showSql" value="true" /> <property name="generateDdl" value="false" /> <property name="databasePlatform" value="oracle.toplink.essentials.platform.database.oracle.OraclePlatform" /> </bean> </property> <property name="loadTimeWeaver"> <bean class="org.springframework.instrument.classloading.InstrumentationLoadTimeWeaver"/> </property> </bean> <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> <property name="entityManagerFactory" ref="entityManagerFactory"/> <property name="dataSource" ref="dataSource"/> </bean> <tx:annotation-driven/> <bean class="org.springframework.orm.jpa.support.PersistenceAnnotationBeanPostProcessor" />
I also added the file persistence.xml with some TL specific settings.
<persistence-unit name="stuf" transaction-type="RESOURCE_LOCAL"> <provider>oracle.toplink.essentials.PersistenceProvider</provider> <class>Foo</class> <class>Bar</class> <properties> <property name="toplink.weaving" value="false" /> <property name="toplink.logging.timestamp" value="false" /> <property name="toplink.logging.thread" value="false" /> <property name="toplink.logging.session" value="false" /> <property name="toplink.throw.orm.exceptions" value="true" /> </properties> </persistence-unit>
Snags
Id generation strategy
The database independent way of generating primary keys in JPA is using the @GeneratedValue(strategy=GenerationType.AUTO) annotation. TL's implementation expects a table named SEQUENCE to be present. Here is the script for an Oracle database.
CREATE TABLE "SEQUENCE" ( "SEQ_NAME" VARCHAR2(50 BYTE) NOT NULL ENABLE, "SEQ_COUNT" NUMBER(38,0) DEFAULT 0 NOT NULL ENABLE, CONSTRAINT "SEQUENCE_PK" PRIMARY KEY ("SEQ_NAME") ENABLE ) ;
Note that the case of the tablename should be the default of the underlying database. So for Oracle this is uppercase, for PostgreSQL it is lowercase.
Maven dependencies
Unfortunately - but not unexpectedly mr. Elli$on - the jars are not available in the main maven repository. So we have to load it into the local repo by hand.
For my own convience I attached the jar and pom file. The maven command to install them:
mvn install:install-file -Dfile=<path-to-file> -DpomFile=<path-to-file> -DgroupId=com.oracle.toplink -DartifactId=toplink-essentials -DcreateChecksum=true
Next the following dependency can be added to the project's pom.
<dependency> <groupId>com.oracle.toplink</groupId> <artifactId>toplink-essentials</artifactId> <version>2.0-b58fcs</version> </dependency>