This tutorial contains notes about Eclipse Link.
1. EclipseLink
EclipseLink is a JPA implementation like Hibernate, OpenJPA and others. It belongs to the Eclipse foundation and plays well with other Eclipse and OSGi technologies.
2. Exercise - Setting up a target definition
In this exercise, you define the dependencies, which are necessary to create a EclipseLink JPA application.
2.1. Creating a target definition project
Create a general project called com.vogella.jpa.target.
Inside this project a target definition file called com.vogella.jpa.target.target should be created.

The following update sites are supposed to be used:

2.2. Validate
Press Set as Active Target Platform once the update sites are resolved and ready. In the following exercises the bundles from these update sites are used.
3. Exercise - Creating a JPA model
3.1. Target
Specify a Todo model together with a service interface, which will be used to get Todo objects.
3.2. Creating the model bundle
Create a plug-in project called com.vogella.jpa.model with javax.persistence as bundle dependency.
Then create a Task
and TodoService
class inside the com.vogella.jpa.model package.
package com.vogella.jpa.model;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
@Entity
public class Todo {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String summary;
private String description;
// empty constructor for JPA instantiation
public Todo() {
}
public Todo(int id) {
this(id, "", "");
}
public Todo(int id, String summary, String description) {
this.id = id;
this.summary = summary;
this.description = description;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getSummary() {
return summary;
}
public void setSummary(String summary) {
this.summary = summary;
}
public String getDescription() {
return description;
}
public void setDescription(String description) {
this.description = description;
}
@Override
public String toString() {
return "Todo [id=" + id + ", summary=" + summary + ", description=" + description + "]";
}
}
package com.vogella.jpa.model;
import java.util.List;
import java.util.Optional;
import java.util.function.Consumer;
public interface TodoService {
void getTodos(Consumer<List<Todo>> todosConsumer);
boolean saveTodo(Todo newTodo);
Optional<Todo> getTodo(int id);
boolean deleteTodo(int id);
void printTodos();
}
Do not forget to export the com.vogella.jpa.model package, so that it can be used by other plugins.
4. Exercise - Creating a JPA service implementation
4.1. Target
Provide a service implementation of the previously created TodoService
, which makes use of Eclipse Link, a H2 Database Engine and JPA.
4.2. Creating the service bundle
Create a plug-in project called com.vogella.jpa.service with the following bundle dependencies:
-
javax.persistence
-
org.eclipse.persistence.jpa
-
org.h2
and package imports
-
com.vogella.jpa.model
-
org.osgi.service.component.annotations (as optional dependency)

Please activate the Generate descriptors from annotated sources preference, so that the component xml file will be created automatically for the ![]() |
The TodoServiceImpl
, which impelements the TodoService
interface should look like this:
package com.vogella.jpa.service;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.concurrent.atomic.AtomicInteger;
import java.util.function.Consumer;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.TypedQuery;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Root;
import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.jpa.PersistenceProvider;
import org.osgi.service.component.annotations.Activate;
import org.osgi.service.component.annotations.Component;
import org.osgi.service.component.annotations.Deactivate;
import com.vogella.jpa.model.Todo;
import com.vogella.jpa.model.TodoService;
@Component(service = TodoService.class, property = { "osgi.command.scope=test", "osgi.command.function=printTodos" })
public class TodoServiceImpl implements TodoService {
private static AtomicInteger current = new AtomicInteger(1);
private EntityManagerFactory entityManagerFactory;
private EntityManager entityManager;
@Activate
@SuppressWarnings("unchecked")
protected void activateComponent() {
@SuppressWarnings("rawtypes")
Map map = new HashMap();
map.put(PersistenceUnitProperties.CLASSLOADER, getClass().getClassLoader());
PersistenceProvider persistenceProvider = new PersistenceProvider();
entityManagerFactory = persistenceProvider.createEntityManagerFactory("h2-eclipselink", map);
entityManager = entityManagerFactory.createEntityManager();
getTodos(todos -> {
if(todos.isEmpty()) {
List<Todo> initialModel = createInitialModel();
initialModel.forEach(this::saveTodo);
}
});
}
@Deactivate
protected void deactivateComponent() {
entityManager.close();
entityManagerFactory.close();
entityManager = null;
entityManagerFactory = null;
}
public TodoServiceImpl() {
}
@Override
public void getTodos(Consumer<List<Todo>> todosConsumer) {
CriteriaBuilder cb = entityManager.getCriteriaBuilder();
CriteriaQuery<Todo> cq = cb.createQuery( Todo.class );
Root<Todo> rootTodo = cq.from( Todo.class );
CriteriaQuery<Todo> allTodos = cq.select( rootTodo );
TypedQuery<Todo> todosQuery = entityManager.createQuery( allTodos );
List<Todo> todoList = todosQuery.getResultList();
todosConsumer.accept(todoList);
}
// create or update an existing instance of Todo
@Override
public synchronized boolean saveTodo(Todo newTodo) {
// hold the Optional object as reference to determine, if the Todo is
// newly created or not
Optional<Todo> todoOptional = getTodo(newTodo.getId());
// get the actual todo or create a new one
Todo todo = todoOptional.orElse(new Todo(current.getAndIncrement()));
todo.setSummary(newTodo.getSummary());
todo.setDescription(newTodo.getDescription());
// send out events
if (todoOptional.isPresent()) {
entityManager.getTransaction().begin();
entityManager.merge(todo);
entityManager.getTransaction().commit();
} else {
entityManager.getTransaction().begin();
entityManager.persist(todo);
entityManager.getTransaction().commit();
}
return true;
}
@Override
public Optional<Todo> getTodo(int id) {
entityManager.getTransaction().begin();
Todo find = entityManager.find(Todo.class, id);
entityManager.getTransaction().commit();
return Optional.ofNullable(find);
}
@Override
public boolean deleteTodo(int id) {
entityManager.getTransaction().begin();
Todo find = entityManager.find(Todo.class, id);
entityManager.remove(find);
entityManager.getTransaction().commit();
return true;
}
@Override
public void printTodos() {
getTodos(todoList -> todoList.forEach(System.out::println));
}
private List<Todo> createInitialModel() {
List<Todo> list = new ArrayList<>();
list.add(createTodo("Application model", "Flexible and extensible"));
list.add(createTodo("DI", "@Inject as programming mode"));
list.add(createTodo("OSGi", "Services"));
list.add(createTodo("SWT", "Widgets"));
list.add(createTodo("JFace", "Especially Viewers!"));
list.add(createTodo("CSS Styling", "Style your application"));
list.add(createTodo("Eclipse services", "Selection, model, Part"));
list.add(createTodo("Renderer", "Different UI toolkit"));
list.add(createTodo("Compatibility Layer", "Run Eclipse 3.x"));
return list;
}
private Todo createTodo(String summary, String description) {
return new Todo(current.getAndIncrement(), summary, description);
}
}
The osgi.command.scope and osgi.command.function properties in the @Component
definition allows to call certain methods, e.g., the printTodos
method, from the command line by using the felix gogo shell.
The @Activate
and @Deactivate
annotations ensure that the activateComponent
and deactivateComponent
methods will be called once the service is activated or deactivated.
To persist Todo objects in the H2 database certain properties for the so called persistence-unit have to be specified in a persistence.xml file, which is supposed to be located in the META-INF folder of the projects right besides the MANIFEST.MF file.
The contents of the persistence.xml should look like this:
<?xml version="1.0" encoding="UTF-8" ?>
<persistence
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd"
xmlns="http://java.sun.com/xml/ns/persistence"
version="2.0">
<persistence-unit name="h2-eclipselink" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.vogella.jpa.model.Todo</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.h2.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:h2:~/h2db/vogellaDB" />
<property name="javax.persistence.jdbc.user" value="sa" />
<property name="eclipselink.ddl-generation" value="create-or-extend-tables" />
<property name="eclipselink.ddl-generation.output-mode" value="database" />
<property name="eclipselink.logging.level" value="FINE" />
</properties>
</persistence-unit>
</persistence>
Make sure that all the files like persistence.xml and the com.vogella.jpa.service.TodoServiceImpl.xml are mentioned in the build.properties file. |
4.3. Validate
Go to the Debug Configurations and create a new OSGi Framework configuration.
Select the com.vogella.jpa.model and com.vogella.jpa.service bundles from the workspace and hit the Add Required Bundles button.

When running the new OSGi Framework configuration the OSGi console should appear in the Console view, where you can type the following:
osgi> test:printTodos
The console should show the following output:

The test:printTodos command is related to the properties in the |
5. Exercise - Using the JPA service as standalone application
In the Creating a JPA service implementation
chapter an OSGi Framework configuration has been used to start the OSGi runtime together with the JPA service from the IDE.
In this exercise the OSGi runtime will be started outside the Eclipse IDE.
See OSGi Tutorial for further information.
5.1. Creating a product with proper configuration
Usually products are used to create rich client applications, but for the sake of generating the predefined structure and aggregation of necessary bundles a slightly tweaked product can be used.
Create a general project called com.vogella.jpa.product and create a Product Configuration called com.vogella.jpa.product.
Switch to the contents tab and add the following bundles to it:
-
com.vogella.jpa.model
-
com.vogella.jpa.service
-
org.eclipse.equinox.console
-
org.apache.felix.gogo.command
-
org.apache.felix.gogo.runtime
-
org.apache.felix.gogo.shell
-
org.eclipse.equinox.simpleconfigurator
-
org.apache.felix.src
After that press the Add Required Plug-ins button to add all necessary dependencies.
Create a config.ini file with the following contents in the root folder besides the com.vogella.jpa.product file:
osgi.bundles=reference\:file\:plugins/org.eclipse.equinox.simpleconfigurator_1.1.200.v20160504-1450.jar@1\:start
org.eclipse.equinox.simpleconfigurator.configUrl=file\:org.eclipse.equinox.simpleconfigurator/bundles.info
osgi.bundles.defaultStartLevel=4
osgi.noShutdown=true
eclipse.ignoreApp=true
On the Configuration tab of the product this config.ini file can be referenced.

Now the product can be exported.

A proper Destination has to be chosen and Generate p2 repository is not necessary and Syncronize before exporting won’t work because there is no product specifying bundle.
As final step before the exported product can be started the org.eclipse.osgi bundle, e.g., org.eclipse.osgi_3.11.2.v20161107-1947.jar, has to be copied into the root folder of the exported product.
Currently custom config.ini files are not considered by the product export. See Bug 284732. So please ensure that the exported product’s config.ini file looks like specified above. |
5.2. Validate
After making all these changes the folder structure of the exported product should look similar to this:

Now the application can be run from the command line by starting it like this:
java -jar org.eclipse.osgi_3.11.2.v20161107-1947.jar -console
After executing this the OSGi console should appear.
To check whether the JPA service is properly working the test:printTodos
command can be invoked again.

6. EclipseLink resources
Sources of this tutorial - https://github.com/SimonScholz/com.vogella.jpa
6.1. vogella Java example code
endifdef::printrun[]
If you need more assistance we offer Online Training and Onsite training as well as consulting