Skip to main content

Notice: This Wiki is now read only and edits are no longer possible. Please see: https://gitlab.eclipse.org/eclipsefdn/helpdesk/-/wikis/Wiki-shutdown-plan for the plan.

Jump to: navigation, search

Scout/Tutorial/5.0/EclipseLink Integration

< Scout‎ | Tutorial‎ | 5.0

This tutorial walks you through setting up EclipseLink within Eclipse Scout. You will need:

  1. Eclipse scout (https://eclipse.org/scout/downloads/)
  2. EclipseLink (https://www.eclipse.org/eclipselink/downloads/)
  3. The Minicrm example database (https://wiki.eclipse.org/Scout/Tutorial/3.9/Minicrm/Get_example_database)

Setup workspace

Basically, follow the minicrm tutorial (https://wiki.eclipse.org/Scout/Tutorial/3.9/Minicrm/Minicrm_Step-by-Step) until you have created the company table, including the server-side data loading using SQL. Later we'll replace the SQL with Eclipselink calls.

So on your client side, your CompanyTablePage loads data like:

 @Override
 protected void execLoadData(SearchFilter filter) throws ProcessingException {
   CompanyTablePageData pageData = SERVICES.getService(IStandardOutlineService.class).loadCompanyData();
   importPageData(pageData);
 }

and on your server side, your StandardOutlineService loads data like:

 @Override
 public CompanyTablePageData loadCompanyData() throws ProcessingException {
   CompanyTablePageData pageData = new CompanyTablePageData();
   SQL.selectInto("SELECT COMPANY_NR, SHORT_NAME, NAME, SECTOR_ID, TYPE_UID, RATING_UID FROM MINICRM.COMPANY INTO :companyNr, :shortName, :name, :sector, :type, :rating", pageData);
   return pageData;
 }

So now we have it working the "old" way. Time for an upgrade.

Configure EclipseLink

In the Scout Explorer, open the server tree, right-click on Libraries and select 'New Library Bundle...'.

Eclipselink 1.png

Add eclipselink.jar and javax.persistence_2.1.0.v201304241213.jar (which you find inside the EclipseLink download) and click Next.

Eclipselink 2.png

Name the bundle something like 'org.eclipsescout.demo.minicrm.server.eclipselink'. Choose the 'Create a plug-in...' option and click Finish.

Eclipselink 3.png

If you look in the Package Explorer view you should see a new bundle called 'org.eclipsescout.demo.minicrm.server.eclipselink'.

Create a persistence.xml file inside the META-INF folder of your server bundle. This file tells EclipseLink things like how to connect, where to find the JDO objects, etc. It should look something like:

<?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"
  version="2.0" xmlns="http://java.sun.com/xml/ns/persistence">
  <persistence-unit name="jdo" transaction-type="RESOURCE_LOCAL">
    <class>org.eclipsescout.demo.minicrm.server.jdo.CompanyJdo</class>
    <properties>
      <property name="javax.persistence.jdbc.driver" value="org.apache.derby.jdbc.EmbeddedDriver" />
      <property name="javax.persistence.jdbc.url" value="jdbc:derby:E:\\temp\\DerbyDB" />
      <property name="javax.persistence.jdbc.user" value="" />
      <property name="javax.persistence.jdbc.password" value="" />
    </properties>
  </persistence-unit>
</persistence>

Create the accompanying CompanyJdo class as follows:

package org.eclipsescout.demo.minicrm.server.jdo;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;

@Entity
@Table(name = "company", schema = "minicrm")
public class CompanyJdo {

  @Id
  @Column(name = "company_nr")
  private long companyNr;

  @Column(name = "short_name")
  private String shortName;

  @Column(name = "name")
  private String name;

  @Column(name = "sector_id")
  private Integer sector;

  @Column(name = "type_uid")
  private Integer type;

  @Column(name = "rating_uid")
  private Integer rating;

}

Now select Source -> Generate Getters and Setters -> Select All > OK and your JDO bean is ready.

Create an OSGI service

Here we instantiate the entity manager and make it available as an OSGI service within the server.

In the server bundle, create the EntityManagerService as follows:

package org.eclipsescout.demo.minicrm.server.eclipselink;

import java.util.HashMap;
import java.util.Map;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;

import org.eclipse.persistence.config.PersistenceUnitProperties;
import org.eclipse.persistence.jpa.PersistenceProvider;
import org.eclipse.scout.service.AbstractService;
import org.osgi.framework.ServiceRegistration;

public class EntityManagerService extends AbstractService {

  private static final String PERSISTENCE_UNIT_NAME = "jdo";
  private EntityManager m_entityManager;

  @Override
  public void initializeService(ServiceRegistration registration) {
    super.initializeService(registration);

    Map<String, Object> properties = new HashMap<>();
    // pass the bundles classloader as property, for use in OSGI
    properties.put(PersistenceUnitProperties.CLASSLOADER, getClass().getClassLoader());

    PersistenceProvider persistenceProvider = new PersistenceProvider();
    EntityManagerFactory factory = persistenceProvider.createEntityManagerFactory(PERSISTENCE_UNIT_NAME, properties);
    m_entityManager = factory.createEntityManager();
  }

  @Override
  public void disposeServices() {
    m_entityManager.close();
    super.disposeServices();
  }

  /**
   * @return the entityManager
   */
  public EntityManager getEntityManager() {
    return m_entityManager;
  }
}

Open the server bundle's plugin.xml, switch to the Extensions tab and expand the 'org.eclipse.scout.service.services' extension. You can see existing registered server-side services.

Add our own by right-clicking on 'org.eclipse.scout.service.services' and selecting New -> service.

Eclipselink 4.png

Copy in the fully-qualified name of the EntityManagerService class in the 'class' field, and copy all other values from the existing service registrations (factory, session, createImmediately).

Eclipselink 5.png

With this step complete, it should be possible to access the EntityManager by calling SERVICES.getService(EntityManagerService.class).getEntityManager().

Start using EclipseLink

Okay lets go! Go to StandardOutlineService.loadCompanyData() and comment out that pesky SQL statement. In its place, write:

  @Override
  public CompanyTablePageData loadCompanyData() throws ProcessingException {
    CompanyTablePageData pageData = new CompanyTablePageData();
//    SQL.selectInto("SELECT COMPANY_NR, SHORT_NAME, NAME, SECTOR_ID, TYPE_UID, RATING_UID FROM MINICRM.COMPANY INTO :companyNr, :shortName, :name, :sector, :type, :rating", pageData);

    EntityManager entityManager = SERVICES.getService(EntityManagerService.class).getEntityManager();
    TypedQuery<CompanyJdo> query = entityManager.createQuery("SELECT c FROM " + CompanyJdo.class.getSimpleName() + " c ", CompanyJdo.class);
    for (CompanyJdo companyJdo : query.getResultList()) {
      CompanyTableRowData row = pageData.addRow();
      row.setCompanyNr(companyJdo.getCompanyNr());
      row.setShortName(companyJdo.getShortName());
      row.setName(companyJdo.getName());
      row.setSector(companyJdo.getSector());
      row.setType(companyJdo.getType());
      row.setRating(companyJdo.getRating());
    }

    return pageData;
  }

Notice that I prefer to use CompanyJdo.class.getSimpleName() over a String value "CompanyJdo" as it is more robust to refactoring.

"But that's a lot more code just to do the same thing! What good is it?"

Just try renaming one of your columns in the client-side CompanyTablePage and you'll see. :)

Bonus task

The SERVICES.getService(EntityManagerService.class).getEntityManager() call is a bit clunky. One way to simplify this is to create a delegate class in the server bundle similar to SQL. Put a private instance of EntityManager in it, and use the 'Source -> Generate Delegate Methods...' feature to populate it. Then remove the instance variable and add in SERVICE.getService()... where required.

For more information on JPA, I recommend Lars Vogel and Simon Scholz's tutorial on JPA 2.0 with EclipseLink (http://www.vogella.com/tutorials/JavaPersistenceAPI/article.html).

Copyright © Eclipse Foundation, Inc. All Rights Reserved.