Persistenz und JSON APIs
Nachdem die Persistence Unit erstellt worden ist, geht es mit der Implementierung des Service weiter. Damit Objekte gelesen und geschrieben werden können, ist ein EntityManager-Objekt notwendig. Das kann aus einem EntityManagerFactory-Objekt erstellt werden. Die eigentliche JPA-Serviceimplementierung ist relativ trivial und bedient sich der JPA-Standard-APIs (Listing 2). Interessanter wird die Sache bei der Erstellung der OSGi-DS-Komponente. Der JPA-Provider stellt für jede gefundene Persistence Unit automatisch einen EntityManagerFactoryBuilder-Service zur Verfügung. Mit diesem lassen sich EntityManagerFactory-Objekte erzeugen. Diese Abstraktion erlaubt das Setzen weiterer Properties, falls beispielsweise die Persistence Unit keine Datenbankverbindungseinstellungen enthält. Man spricht bei einer Persistence Unit ohne Datenbankverbindungseinstellungen auch von einer unvollständigen. Bei einer vollständigen Persistence Unit sucht der JPA-Provider automatisch nach einem kompatiblen Data-Source-Provider und stellt zusätzlich ein fertiges EntityManagerFactory-Objekt als OSGi Service zur Verfügung.
Im Beispiel-Bundle wird eine unfertige Persistence Unit definiert, daher muss der EntityManagerFactoryBuilder genutzt werden. Allerdings hat man dadurch auch mehr Freiheit zur Laufzeit, um beispielsweise die Datenbankeinstellungen über OSGi Preference einzulesen. Den richtigen EntityManagerFactoryBuilder-Service erhält man durch die Angabe eines Servicefilters mit dem Namen der Persistence Unit in der DS-Komponentendefinition (Listing 3). Das fertige Projekt ist in Abbildung 1 zu sehen und kann auch online abgerufen werden [1].
Listing 2: JPA-GreetingService-Implementierung
// GreetingService (already defined in hello.service bundle) public interface GreetingService { /** Returns a list of all available greetings. */ CollectiongetGreetings() throws Exception; /** Adds a new greeting. */ void sayHello(final String greeting) throws Exception; } // JPA Implementation of {@link GreetingService} public class JpaGreetingServiceImpl implements GreetingService { private final EntityManagerFactory emf; public JpaGreetingServiceImpl(EntityManagerFactory emf) { this. emf = emf; } public Collection getGreetings() throws Exception { final EntityManager em = emf.createEntityManager(); final TypedQuery q = em.createQuery( "SELECT g FROM GreetingEntity g ORDER BY g.created desc", GreetingEntity.class); final List results = q.getResultList(); final List greetings = new ArrayList (results.size()); for (final GreetingEntity entity : results) { greetings.add(entity.getText()); } em.close(); return Collections.unmodifiableList(greetings); } public void sayHello(final String greeting) throws Exception { final EntityManager em = emf.createEntityManager(); final GreetingEntity entity = new GreetingEntity(); entity.setCreated(System.currentTimeMillis()); entity.setText(greeting.getText()); em.getTransaction().begin(); em.persist(entity); em.getTransaction().commit(); em.close(); } }
Listing 3: JPA-GreetingService-OSGi-DS-Komponente
OSGI-INF/jpa-greeting-service.xml:JpaGreetingServiceComponent.java: public class JpaGreetingServiceComponent implements GreetingService { private GreetingService service; public void activate(final ComponentContext context) { final EntityManagerFactoryBuilder emfBuilder = (EntityManagerFactoryBuilder) context.locateService("EntityManagerFactoryBuilder");; // disable Gemini JPA/EclipseLink data source handling for NoSQL final Map props = new HashMap (2); props.put("javax.persistence.nonJtaDataSource", ""); props.put("gemini.jpa.providerConnectedDataSource", Boolean.TRUE); // configure MongoDB connection props.put("eclipselink.target-database", "org.eclipse.persistence.nosql.adapters.mongo.MongoPlatform"); props.put("eclipselink.nosql.connection-spec", "org.eclipse.persistence.nosql.adapters.mongo.MongoConnectionSpec"); props.put("eclipselink.nosql.property.mongo.host", "localhost"); props.put("eclipselink.nosql.property.mongo.db", "jpamongodb"); // create EntityManagerFactory and service emf = emfBuilder.createEntityManagerFactory(props); service = new JpaGreetingServiceImpl(emf); } public void deactivate(final ComponentContext context) { emf.close(); emf = null; // close EMF service = null; // dispose real service } public Collection getGreetings() throws Exception { return getService().getGreetings(); } public GreetingService getService() { final GreetingService greetingService = service; if (greetingService == null) throw new IllegalStateException("inactive"); return greetingService; } public void sayHello(final String greeting) throws Exception { getService().sayHello(greeting); } } META-INF/MANIFEST.MF: Manifest-Version: 1.0 Bundle-SymbolicName: hello.jpa ... Service-Component: OSGI-INF/jpa-greeting-service.xml Bundle-ActivationPolicy: lazy build.properties: bin.includes = META-INF/, ., OSGI-INF/ ...

Hinterlasse einen Kommentar