CDO/Hibernate Store/Tutorial

From Eclipsepedia

Jump to: navigation, search

Contents


This tutorial assumes that the required dependencies are installed.

Download the example projects from CVS

As a first step download the example projects from CVS, see here for the CVS location information.

After downloading it is possible that you need to clean all the projects, goto Project > Clean (and clean all projects). The projects should not show any error messages.

After performing the above steps the Project Explorer should look like this:


Org.eclipse.emf.cdo.hibernate.project explorer.png

Details of the example projects

Before continuing take some time to study the projects.

The org.eclipse.emf.cdo.examples.company project contains the model. Instances of this model will be persisted. The model has been prepared for CDO. The interfaces inherit from CDOObject and the impl classes from CDOObjectImpl.

The org.eclipse.emf.cdo.examples.hibernate.server project contains the server side configuration files. This plugin is used on the server, it has been added to the launch configuration of the server. The org.eclipse.emf.cdo.examples.hibernate.server project contains a number of important files:

  • config/cdo-server.xml: the CDO server config file, for more information see the configuration page
  • META-INF/company_model_teneo_annotations.xml: contains JPA annotations which control how the model is mapped to the database. In this case there is only a simple annotation which controls the table name of the Address EClas.
  • META-INF/MANIFEST.MF: the plugin has been set to depend on org.eclipse.emf.cdo.server.hibernate.teneo, using the Eclipse buddy loading policy this makes the annotations xml file visible for the Hibernate/Teneo plugins

The org.eclipse.emf.cdo.examples.hibernate.client project contains the client side code. The actual runnable code consists of 2 test cases. Both test cases extend from BaseTest which contains the client-server connection code. The test cases are discussed in more detail below.

Start the CDO Server

As a next step, start the CDO server. To do this open the org.eclipse.emf.cdo.examples.hibernate.server project and right click on the CDOHibernateServer.launch and do: Run As > CDOHibernateServer. This launch configuration loads all plugins in the Eclipse installation and workspace so it takes some time to start the CDO server (around 10 seconds).

Org.eclipse.emf.cdo.console.png

Note: Check in the console if you don't see an exception like this: java.net.BindException: Address already in use. If so stop the CDO server (in the console view, small red button), check the Debug view if you see any running CDO server processes, if so terminate them. Then also check on operating system level if you don't see CDO server processes (sometimes they are not shown in the Debug view) and kill/stop them.

At this point there is a running CDO Server using Hibernate and Teneo. The server uses hsqldb so it is not directly possible to see the database. It is quite easy to change this to mysql or another database (check the cdo-server.xml in the config folder, if you change it you need to restart the cdo server).

Run client code: QuickStartTest

The CDO server runs so now it is time to start running some client code. The client code can be found in the org.eclipse.emf.cdo.examples.hibernate.client project. Go to the src folder and navigate to the test cases. You will find three classes, one base parent class (BaseTest) and 2 junit test cases. Let's look at them in some detail.

The BaseTest class contains client-server connection code.

The initialize method builds the connection code and creates a CDOSessionConfiguration. The test cases use the TCP connector and CONNECTION_ADDRESS constant (which is localhost:2036). TCP and the portnumber are also specified in the cdo-server.xml, so the client and server use the same settings.

    OMPlatform.INSTANCE.setDebugging(true);
    OMPlatform.INSTANCE.addLogHandler(PrintLogHandler.CONSOLE);
    OMPlatform.INSTANCE.addTraceHandler(PrintTraceHandler.CONSOLE);
 
    // Prepare container
    final IManagedContainer container = ContainerUtil.createContainer();
    Net4jUtil.prepareContainer(container); // Register Net4j factories
    TCPUtil.prepareContainer(container); // Register TCP factories
    CDONet4jUtil.prepareContainer(container); // Register CDO factories
    container.activate();
 
    // Create connector
    final IConnector connector = TCPUtil.getConnector(container, CONNECTION_ADDRESS);
 
    // Create configuration
    sessionConfiguration = CDONet4jUtil.createSessionConfiguration();
    sessionConfiguration.setConnector(connector);
    sessionConfiguration.setRepositoryName(REPO_NAME);

The sessionConfiguration is used in the openSession method to create a session and register the EPackage:

  protected CDOSession openSession()
  {
    if (sessionConfiguration == null)
    {
      initialize();
    }
    final CDOSession cdoSession = sessionConfiguration.openSession();
    cdoSession.getPackageRegistry().putEPackage(CompanyPackage.eINSTANCE);
    return cdoSession;
  }

The EPackage is defined/generated in the org.eclipse.emf.cdo.examples.company project. The openSession method is called by the two subclasses.

As the BaseTest class has been discussed let's move to the first simple test case, the QuickStartTest contains a single test method. The first part:

    // first create an address and persist it
    final String addressName = "name " + System.currentTimeMillis(); //$NON-NLS-1$
    {
      final CDOSession session = openSession();
      final CDOTransaction transaction = session.openTransaction();
      // get/create a resource
      CDOResource resource = transaction.getOrCreateResource("/res1"); //$NON-NLS-1$
 
      // clear any previous data
      resource.getContents().clear();
 
      final Address address = CompanyFactory.eINSTANCE.createAddress();
      address.setCity("test"); //$NON-NLS-1$
      address.setName(addressName);
      address.setStreet("test"); //$NON-NLS-1$
      resource.getContents().add(address);
 
      transaction.commit();
      session.close();
    }

The above code does the following:

  1. open a session and transaction
  2. create or get a resource, all data access takes place with an active resource
  3. create an address with some simple data, and add it to the resource
  4. commit (saves the resource) and close

Now the test case needs to check if the address actually got saved:

    {
      final CDOSession session = openSession();
      final CDOTransaction transaction = session.openTransaction();
      CDOResource resource = transaction.getResource("/res1"); //$NON-NLS-1$
      assertTrue(resource.getContents().get(0) instanceof Address);
      assertEquals(1, resource.getContents().size());
      final Address address = (Address)resource.getContents().get(0);
      assertEquals(addressName, address.getName());
      transaction.commit();
      session.close();
    }

This reads the resource back and checks the content. We should find only one object and that should have the same information as persisted in the beginning.

Now run the test case, right click on it and then: Run As > Junit testcase. You should see a green bar after a few seconds. Also check out the console. Depending on which version of CDO/Teneo you are running you should see log statements showing actual activities and mappings taking place.


Run client code: HibernateQueryTest

The next test case shows some more advanced behavior, mainly the many different types of HQL queries which can be used on the client. See this page for a detailed description of the queries in this testcase. In this tutorial we will only do a quick review.

The HibernateQueryTest consists of 2 distinct parts: 1) creation of a test set, 2) query and check query results. The test data generation can be controlled with a number of static members in the top of the class:

private static final int NUM_OF_PRODUCTS = 20;
private static final int NUM_OF_CUSTOMERS = 5;
private static final int NUM_OF_PRODUCTS_CUSTOMER = NUM_OF_PRODUCTS / NUM_OF_CUSTOMERS;
private static final int NUM_OF_SALES_ORDERS = 5;

You can change these values to increase the test volume. But before doing that first run the test case as it is to be sure that it passes fine in its current form.

A number of methods are involved in generating the test data: fillResource, createSalesOrder, etc.

Now let's move to a first query test case (truncated a bit for this page):

  public void testSimpleQueries() throws Exception
  {
    CDOSession session = openSession();
    CDOTransaction transaction = session.openTransaction();
    {
      CDOQuery cdoQuery = transaction.createQuery("hql", "from Product"); //$NON-NLS-1$  //$NON-NLS-2$
      final List<Product> products = cdoQuery.getResult(Product.class);
      assertEquals(NUM_OF_PRODUCTS, products.size());
    }
    {
      CDOQuery cdoQuery = transaction.createQuery("hql", "from Product where name=:name"); //$NON-NLS-1$  //$NON-NLS-2$
      cdoQuery.setParameter("name", "" + 1); //$NON-NLS-1$  //$NON-NLS-2$
      final List<Product> products = cdoQuery.getResult(Product.class);
      assertEquals(1, products.size());
    }
    {
      CDOQuery cdoQuery = transaction.createQuery("hql", "from Product where vat=:vat"); //$NON-NLS-1$  //$NON-NLS-2$
      cdoQuery.setParameter("vat", VAT.VAT15); //$NON-NLS-1$ 
      final List<Product> products = cdoQuery.getResult(Product.class);
      assertEquals(10, products.size());
      for (Product p : products)
      {
        assertEquals(p.getVat(), VAT.VAT15);
      }
    }
    transaction.commit();
  }



Wikis: CDO | Net4j | EMF | Eclipse