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

3 comments:

Bruno said...

Hi Shaun,

Thanks so much for responing, and for posting this as a toplevel entry to get the word out to others. I was under the false impression that TopLink 10.1.3.1 was the JPA spec compliant release of TopLink and that it would be possible to use the JPA interfaces with TopLink.

I would consider switching to TopLink essentials and refactoring my code, but what guarantees do I have about the behavior? Are the classes in oracle.toplink.essentials.** exactly the same as those in oracle.toplink.**? Please don't say that they are "essentially" the same. :-) We make use of an awful lot of TopLink features including:
- clustering (still using the legacy CacheSynchronizationManager classes)
- very specific event handlers
- extensions to the Expression API
- extensions to a Platform class
- custom sequence generator
Are all these features supported in TopLink Essentials? My understanding was - NO.

Thanks
- Bruno

Shaun Smith said...

Hi Bruno,

The code in TLE is a fork of the Oracle TopLink code base tuned to implement the JPA spec so the classes in oracle.toplink.essentials.** are substantially--I didn't say 'essentially' ;-)-- the same as the corresponding classes in oracle.toplink.**. Changes were only made for the sake of the spec.

That being said--you're right, TopLink Essentials is missing a few advanced features available in Oracle TopLink, like cache coordination, so what I suggested is really only a good idea if you're doing pretty vanilla Oracle TopLink.

I think what you really should do is wait until the Oracle TopLink 11 preview is available around JavaOne (2nd week of May '07) to start migrating your TopLink app to JPA. This will allow you to use all the features in Oracle TopLink and make use of the Java Persistence programmer API.

--Shaun

Bruno said...

OK, that helps me a lot with my planning. Thanks again for saving us from what would have been a lot of fruitless prototyping!