Accueil > Spring, Spring Data, Spring DM > Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step5]

Eclipse RCP/RAP with Spring DM, Spring Data JPA and Remoting [step5]


In [step4] we have created DAO layer with Mock implementation. In this article we will start to explains how to implement DAO with JPA to use Database. We will use:

  • EclipseLink as JPA Implementation
  • Derby as Database.
  • Spring Data JPA to implement our DAO with JPA. Spring Data gives some DAO interface like org.springframework.data.repository.PagingAndSortingRepository which provides several CRUD methods like :
    • Iterable findAll(): to find all entity.
    • T save(T model): to save an entity.
    • Page findAll(Pageable pageable): to find all entity with pagination.

    The basic idea of Spring Data JPA is extends this interface in your DAO, and you not need to implements this methods with JPA query. It’s the goal of Spring Data JPA.

But it’s very long to explain how to configure and creates bundles to do that. So I decided to split the explanation into 2 articles :

  1. [step5]: explains how to download Spring Data JPA, use Java Spring Data Structure in our Mock and API DAO, and configure the OSGi launch.
  2. [step6]: explains how to create and configure bundles to use Spring Data JPA with EclipseLink and Derby.

Download

You can download eclipsespring_step5.zip which contains the following explained projects :

  • fr.opensagres.domain : OSGi bundle domain which hosts fr.opensagres.domain.User class.
  • fr.opensagres.dao : OSGi bundle Dao API which hosts fr.opensagres.dao.UserDao interface.
  • fr.opensagres.dao.mock : OSGi bundle Dao Mock Implementation (Dao implemented with Java Map) which hosts a Spring file which declares the implementation of UserDao in a Spring bean and publish it the OSGi services registry with Spring DM <osgi:service.
  • fr.opensagres.services : OSGi bundle Services API which hosts fr.opensagres.services.UserService interface.
  • fr.opensagres.services.impl : OSGi bundle Services Implementation which hosts a Spring file which declares the implementation of UserService in a Spring bean and publish it the OSGi services registry with Spring DM <osgi:service.
  • fr.opensagres.data.injector : OSGi bundle Data Injector which hosts a Spring file which declares a DataInjector in a Spring bean. This DataInjector consumes the UserService injected by Spring which is retrieved from the OSGi services registry with Spring DM <osgi:reference and call UserService#saveUser(User user) to inject User data.
  • fr.opensagres.simpleclient : OSGi bundle simple client which hosts a Spring file which declares a thread in a Spring bean. This thread consumes the UserService injected by Spring which is retrieved from the OSGi services registry with Spring DM <osgi:reference.
  • fr.opensagres.config.log4j : OSGi fragment which configures log4j.
  • TargetPlatform: simple project which hosts the Spring DM JARS, the target definition and launch.

To use this zip, unzip it :

  1. import those projects in a workspace.
  2. open the TargetPlatform/eclipsespring.target file and click on Set as Target Platform.
  3. select TargetPlatform/launch/Simple OSGi client.launch and Run it.

TargetPLatform & Spring Data JPA

Here we will download

Download Spring Data JPA

  • delete the TargetPlatform/lib folder.
  • Modify the pom.xml to download Spring Data JPA JARs, etc like this :
    <project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    	xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
    	<modelVersion>4.0.0</modelVersion>
    	<groupId>fr.opensagres.samples</groupId>
    	<artifactId>fr.opensagres.samples.targetplatform</artifactId>
    	<packaging>pom</packaging>
    	<version>0.0.1-SNAPSHOT</version>
    
    	<build>
    		<plugins>
    			<plugin>
    				<groupId>org.apache.maven.plugins</groupId>
    				<artifactId>maven-dependency-plugin</artifactId>
    				<version>2.1</version>
    				<executions>
    					<execution>
    						<id>copy-dependencies</id>
    						<phase>process-resources</phase>
    						<goals>
    							<goal>copy-dependencies</goal>
    						</goals>
    						<configuration>
    							<outputDirectory>lib</outputDirectory>
    							<overWriteReleases>true</overWriteReleases>
    							<overWriteSnapshots>true</overWriteSnapshots>
    							<overWriteIfNewer>true</overWriteIfNewer>
    						</configuration>
    					</execution>
    				</executions>
    			</plugin>
    		</plugins>
    	</build>
    
    	<properties>
    		<spring.dm.version>1.2.1</spring.dm.version>
    		<slf4j.version>1.6.1</slf4j.version>
    		<org.aopalliance>1.0.0</org.aopalliance>
    		<spring.data.jpa>1.0.3.RELEASE</spring.data.jpa>
    		<annotation.version>1.0.1</annotation.version>
    		<jpa.version>1.1</jpa.version>
    		<eclipselink>2.3.0</eclipselink>
    		<commons.dbcp>1.2.2.osgi</commons.dbcp>
    		<database.derby>10.5.1000001.764942</database.derby>
    	</properties>
    
    	<repositories>
    
    		<repository>
    			<id>spring-maven-milestone</id>
    			<name>Springframework Maven Repository</name>
    			<url>http://maven.springframework.org/milestone</url>
    		</repository>
    
    		<repository>
    			<id>com.springsource.repository.bundles.external</id>
    			<name>SpringSource Enterprise Bundle Repository - External Bundle Releases</name>
    			<url>http://repository.springsource.com/maven/bundles/external</url>
    		</repository>
    
    		<repository>
    			<id>EclipseLink Repo</id>
    			<url>http://download.eclipse.org/rt/eclipselink/maven.repo</url>
    		</repository>
    
    	</repositories>
    
    	<dependencies>
    
    		<!-- Spring DM -->
    		<dependency>
    			<groupId>org.springframework.osgi</groupId>
    			<artifactId>spring-osgi-extender</artifactId>
    			<version>${spring.dm.version}</version>
    			<exclusions>
    				<exclusion>
    					<groupId>org.springframework</groupId>
    					<artifactId>*</artifactId>
    				</exclusion>
    			</exclusions>
    		</dependency>
    
    		<!-- API logger: Commons Logging required by Spring DM -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>com.springsource.slf4j.org.apache.commons.logging</artifactId>
    			<version>${slf4j.version}</version>
    			<scope>provided</scope>
    		</dependency>
    
    		<!-- Implementation logger: log4j -->
    		<dependency>
    			<groupId>org.slf4j</groupId>
    			<artifactId>com.springsource.slf4j.log4j</artifactId>
    			<version>${slf4j.version}</version>
    			<scope>provided</scope>
    		</dependency>
    
    		<!-- OSGi AOP Alliance (need do that since we have exclude org.springframework) -->
    		<dependency>
    			<groupId>org.aopalliance</groupId>
    			<artifactId>com.springsource.org.aopalliance</artifactId>
    			<version>${org.aopalliance}</version>
    		</dependency>
    
    		<!-- Spring Data JPA -->
    		<dependency>
    			<groupId>org.springframework.data</groupId>
    			<artifactId>spring-data-jpa</artifactId>
    			<version>${spring.data.jpa}</version>
    		</dependency>
    
    		<!-- API : javax.annotation -->
    		<dependency>
    			<groupId>org.apache.geronimo.specs</groupId>
    			<artifactId>geronimo-annotation_1.1_spec</artifactId>
    			<version>${annotation.version}</version>
    		</dependency>
    
    		<!-- API JPA: annotation -->
    		<dependency>
    			<groupId>org.apache.geronimo.specs</groupId>
    			<artifactId>geronimo-jpa_2.0_spec</artifactId>
    			<version>${jpa.version}</version>
    		</dependency>
    
    		<!-- Implementation JPA: EclipseLink -->
    		<dependency>
    			<groupId>org.eclipse.persistence</groupId>
    			<artifactId>org.eclipse.persistence.jpa</artifactId>
    			<version>${eclipselink}</version>
    		</dependency>
    
    		<!-- Database Connection Pool -->
    		<dependency>
    			<groupId>org.apache.commons</groupId>
    			<artifactId>com.springsource.org.apache.commons.dbcp</artifactId>
    			<version>${commons.dbcp}</version>
    		</dependency>
    
    		<!-- Database Derby -->
    		<dependency>
    			<groupId>org.apache.derby</groupId>
    			<artifactId>com.springsource.org.apache.derby</artifactId>
    			<version>${database.derby}</version>
    		</dependency>
    
    	</dependencies>
    
    </project>
    

    You can notice that org.springframework groupid is excluded in the org.springframework.osgi dependency to avoid downloading Spring 2.5.6 JARs, because Spring Data JPA requires Spring 3.0.5.

  • Open a dos/sh command, go to the folder TargetPlaform and launch mvn like this (or use M2Eclipse) :
    mvn process-resources
  • this command download Spring Data JPA JARs and their dependencies and copy it to the TargetPlatform/lib folder. Once maven has finished, refresh TargetPlatform project, lib folder must appears:

Target Definition

At this step we need to refresh the Target Platform. To do that :

  1. close the editor of TargetPlatform/eclispespring.target.
  2. reopen the editor of TargetPlatform/eclispespring.target. PDE will resolve the target platform and bundles that you have downloaded must appears in the Target Paltform.
  3. Activate the Target Platform with Set as Target Platform link.

The existing launch TargetPlatform/launch/Simple OSGi Client.launch is broken because we have new bundles (for instance Spring 3.0.5 bundles instead of 2.5.6).
We will fix this launch on the end of this article.

Bundles – Mock Dao

To use Spring Data JPA, we need extends the Spring Data org.springframework.data.repository.PagingAndSortingRepository interface in our API UserDao.

DAO API

Modify the fr.opensagres.dao.UserDao interface like this:

package fr.opensagres.dao;

import org.springframework.data.repository.PagingAndSortingRepository;

import fr.opensagres.domain.User;

public interface UserDao extends PagingAndSortingRepository<User, Long> {

	// Iterable<User> findAll();

	// User save(User user);

}

MANIFEST.MF

In the META-INF/MANIFEST-MF of the Dao API bundle:

  • import the org.springframework.data.repository package

Here the full content of this MANIFEST.MF:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Dao API
Bundle-SymbolicName: fr.opensagres.dao
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: fr.opensagres.domain,
 org.springframework.data.repository
Export-Package: fr.opensagres.dao

Mock Dao

We must modify our MockDao to implement the Spring Data interface org.springframework.data.repository.PagingAndSortingRepository. We should do that because we have Mock Dao but when we will use Spring Data JPA, we need not implement the UserDao with JPA. I think it should be cool if Spring Data will provides a new project to manage Mock DAO. I have started this project in the org.springframework.data.domain.collections but it’s an another topic. At this step we implement Mock Dao at hand.

MockUserDao class

Modify the fr.opensagres.dao.mock.MockUserDao class like this:

package fr.opensagres.dao.mock;

import java.util.LinkedHashMap;
import java.util.Map;

import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.data.domain.Sort;

import fr.opensagres.dao.UserDao;
import fr.opensagres.domain.User;

public class MockUserDao implements UserDao {

	private final Map<Long, User> users = new LinkedHashMap<Long, User>();
	private long currentId = 0;

	public Iterable<User> findAll() {
		return users.values();
	}

	public User save(User user) {
		Long id = user.getId();
		if (id == null) {
			id = generateId();
			user.setId(id);
		}
		users.put(id, user);
		return user;
	}

	public synchronized Long generateId() {
		return currentId++;
	}

	public long count() {
		return users.values().size();
	}

	public void delete(Long id) {
		users.remove(id);
	}

	public void delete(User user) {
		users.remove(user);
	}

	public void delete(Iterable<? extends User> users) {
		throw new UnsupportedOperationException();
	}

	public void deleteAll() {
		users.clear();
	}

	public boolean exists(Long id) {
		return users.containsKey(id);
	}

	public User findOne(Long id) {
		return users.get(id);
	}

	public Iterable<User> save(Iterable<? extends User> arg0) {
		throw new UnsupportedOperationException();
	}

	public Iterable<User> findAll(Sort sort) {
		throw new UnsupportedOperationException();
	}

	public Page<User> findAll(Pageable pageable) {
		throw new UnsupportedOperationException();
	}
}

MANIFEST.MF

In the META-INF/MANIFEST-MF of the Dao Mock bundle:

  • import the org.springframework.data.domain package
  • import the org.springframework.data.repository package

Here the full content of this MANIFEST.MF:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Dao Mock Implementation
Bundle-SymbolicName: fr.opensagres.dao.mock
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: fr.opensagres.dao,
 fr.opensagres.domain,
 org.springframework.data.domain,
 org.springframework.data.repository

Servives Implementation

MANIFEST.MF

In the META-INF/MANIFEST-MF of the Services implementation bundle:

  • import the org.springframework.data.domain package
  • import the org.springframework.data.repository package

Here the full content of this MANIFEST.MF:

Manifest-Version: 1.0
Bundle-ManifestVersion: 2
Bundle-Name: Services Implementation
Bundle-SymbolicName: fr.opensagres.services.impl
Bundle-Version: 1.0.0.qualifier
Bundle-RequiredExecutionEnvironment: J2SE-1.5
Import-Package: fr.opensagres.dao,
 fr.opensagres.domain,
 fr.opensagres.services,
 org.springframework.data.domain,
 org.springframework.data.repository

Run Mock

At this step we need fix the TargetPlatform/launch/Simple OSGi client.launch.

to do that, select the org.springframework.data.commons bundle (which provides the org.springframework.data.repository.PagingAndSortingRepository interface) and click on Add required Bundles button to add missing bundles in the selection :

and remove (why is there selected?) at hand some bundles which is not used in our context like:

  • com.springsource.org.apache.commons.pool
  • com.springsource.org.apache.commons.derby
  • org.apache.geronimo.specs.geronimo-specs-jpa_2_0_spec
  • org.eclipse.persistence.antlr
  • org.eclipse.persistence.asm
  • org.eclipse.persistence.core
  • org.eclipse.persistence.jpa

Run the OSGi launch, and you will see on the console the User list :

User [Angelo Zerr]
User [Pascal Leclercq]
User [Amine Bousta]
User [Mickael Baron]
User [Jawher Moussa]
User [Arnaud Cogoluegnes]
User [Lars Vogel]
User [Olivier Gierke]
User [Tom Schindl]
User [Wim Jongman]

Conclusion

In this article we have downloaded JARs bundles to work with Spring Data JPA:

And we have modified our UserDao API to extends Spring Data org.springframework.data.repository.PagingAndSortingRepository interface which will be very helpfull when we will use Spring Data JPA.

In the next article [step6] we will create bundles to use Spring Data JPA with EclipseLink and Derby.

About these ads
Catégories:Spring, Spring Data, Spring DM

Laisser un commentaire

Entrez vos coordonnées ci-dessous ou cliquez sur une icône pour vous connecter:

Logo WordPress.com

Vous commentez à l'aide de votre compte WordPress.com. Déconnexion / Changer )

Image Twitter

Vous commentez à l'aide de votre compte Twitter. Déconnexion / Changer )

Photo Facebook

Vous commentez à l'aide de votre compte Facebook. Déconnexion / Changer )

Photo Google+

Vous commentez à l'aide de votre compte Google+. Déconnexion / Changer )

Connexion à %s

Suivre

Recevez les nouvelles publications par mail.

Rejoignez 170 autres abonnés

%d blogueurs aiment cette page :