Inject your JPA EntityManager into an Eclipse RCP application - Guest post by Nepomuk Seiler
Inject your JPA EntityManager
The dependency injection in Eclipse 4 is really nice. However you cannot inject your EntityManager like in JavaEE6. Until now.
The Gemini JPA project provides an OSGi service implementation for EntityManagers and EntityManagerFactories. A set of database connectors are provided through the Gemini DBAccess project. In order to use these services smoothly with annotations the Gemini Ext Di project was created.
To get started you need to add the following repositories to your target platform
The EclipseLink components are available through Juno/Kepler p2 updatesite.
Assuming you have your model classes and your persistence.xml in one bundle you must add this to the MANIFEST.MF
Meta-Persistence: META-INF/persistence.xml
Now Gemini JPA can recognize your bundle which provides entity classes. Note that the persistence.xml and the entity class must reside in the same bundle.
Next you have to adjust your startup configuration a bit. Open your product file and go to the configuration tab. Add the following three bundles to the start levels configuration
-
your entity bundle: start-level = default; auto-start = true
-
org.eclipse.gemini.dbaccess.
: start-level = 2; auto-start = true -
org.eclipse.gemini.jpa: start-level = 3; auto-start = true
This will assure that all neccessary services are started
The last configuring step is crucial. Go to the Launching tab in your product file and add this line to the VM Arguments
-DREFRESH_BUNDLES=false
This will deactivate weaving for your entity classes, but stops Gemini JPA of restarting your bundles. There seem to be some race conditions, when the cascading restarts restart the ui bundles, so the UI may get destroyed or the application just fails to start.
Now just import the org.eclipse.gemini.ext.di package and you are ready to go. Like this
@Inject @GeminiPersistenceContext(unitName=”puTest”) EntityManager em;
Or inject an EntityManagerFactory
@Inject @GeminiPersistenceUnit(unitName=”puTest”) EntityManager em;
You can even customize your persistence unit within the injection
@Inject @GeminiPersistenceContext(unitName=”puTest”, properties = { @GeminiPersistenceProperty(name=PersistenceUnitProperties.JDBC_DRIVER, value=”org.gjt.mm.mysql.Driver”), @GeminiPersistenceProperty(name=PersistenceUnitProperties.JDBC_URL, value=”jdbc:mysql://127.0.0.1/test”), @GeminiPersistenceProperty(name=PersistenceUnitProperties.JDBC_USER, value=”test”), @GeminiPersistenceProperty(name=PersistenceUnitProperties.JDBC_PASSWORD, value=”test”)) }) EntityManager em;
What? You have stored your db settings via Eclipse Preferences. No problem
@Inject @GeminiPersistenceContext(unitName = “unconfigured2”, properties = { @GeminiPersistenceProperty(name = PersistenceUnitProperties.JDBC_DRIVER, valuePref = @Preference(“jdbc_driver”)), @GeminiPersistenceProperty(name = PersistenceUnitProperties.JDBC_URL, valuePref = @Preference(“jdbc_url”)) }) EntityManager em;
Note that currently there will be no reinjection if the properties are changed during runtime. This will available in future releases.
A complete sample application can be found on GitHub. Please report any bugs or improvements on here. Special thanks to Filipp A. which made the initial contribution.
Author: Nepomuk Seiler is a information sience student at the Ludwigs-Maximilians-University Munich. Checkout recent projects at GitHub or his homepage.