Tuesday, April 17, 2007

Using TopLink projects through JPA

I started writing a response to a comment on my blog about accessing the underlying ServerSession in TopLink Essentials and decided that the question warranted it's own blog entry.

In his comment, Bruno said:
"I'm trying to do the reverse of what you explained here. I want to be able to obtain an EntityManager from an existing ServerSession. My application configures the ServerSession directly, and all the descriptors are configured in code. I now want to be able to use the JPA interfaces for data access, but defer migrating all the mappings until some time later. Can this be done with TopLink 10.1.3.1? It looks like we need to add the toplink-essentials.jar just to get the actual JPA code, but this all depends on the package oracle.toplink.essentials, while we still have many dependencies on the original package path."

Mixing Oracle TopLink classes with TopLink Essentials JPA isn't really possible--you need to choose one or the other. If you're interested in using the spec compliant JPA programmer API then you should use Essentials. The next release of Oracle TopLink will be spec compliant and offer access to advanced TopLink features. A preview of the JPA compliant Oracle TopLink will be available around JavaOne, the second week of May.

In the meantime, if you can't wait, you can bring your hand coded TopLink Project and Descriptors to TopLink Essentials. The process involves replacing toplink.jar on your classpath with toplink-essentials.jar and changing the package imports in your Project to use the TLE classes instead of the Oracle TopLink ones. Once your code is compiling, you can create a ServerSession and wrap it in an EntityManagerFactory.


Project project = new MyProject();
final ServerSession serverSession = new ServerSession(project);
EntityManagerFactory emf = new EntityManagerFactoryImpl(serverSession);
EntityManager em = emf.createEntityManager();


Now you can use all the features of JPA including JPQL.


public void test() throws Exception {

Project project = new MyProject();
final ServerSession serverSession = new ServerSession(project);
EntityManagerFactory emf = new EntityManagerFactoryImpl(serverSession);
EntityManager em = emf.createEntityManager();

em.getTransaction().begin();
em.createQuery("Delete from A").executeUpdate();
A a = new A();
a.setId(1l);
em.persist(a);
em.getTransaction().commit();

List <A> results = em
.createQuery("select a from A a")
.getResultList();

for (A eachA : results) {
System.out.println(eachA);
}
serverSession.logout();
}


Pretty cool!

--Shaun