Skip to content

March 6, 2009

24

Using Teneo and EMF to store your data

Most of you know that I am working as a committer for various Eclipse-related projects (such as Xtext, Xpand and the Modeling Workflow Engine). You might not know, however, that I also work as a consultant for itemis. On one of my recent consulting assignments in Ottawa, Canada, I was asked "How can we use EMF to store our data in a database?"

Well, it turns out EMF can help a long way to store data in a database. Here is how.
Prepare your development environment

  1. Get Eclipse 3.5 M5 (click here to download)
  2. Unpack and start Eclipse
  3. Bring up the "Install New Software" dialog (Help -> Install New Software)
  4. Select Teneo EMF Hibernate Runtime and Teneo EMF Hibernate SDK, version 1.0.3
  5. Cick Finish
  6. You most probably will be asked to restart Eclipse.

Create a target definition that includes Hibernate and HSQLDB
In order to keep things simple, we will store the data in an HSQLDB database. We will use the Hibernate OR Mapper to perform the mapping between your data objects and the database. As you might guess, quite a number of libraries will be involved to get the task accomplished. Instead of creating a bunch of plug-in projects containing the respective libraries, or - even worse - copying all libraries into our project, we'll set up a target definition. Target definitions help to maintain a common set of dependencies for all developers on a team, which is a Good Thing.

  1. Create a new project library.target (File -> New -> Project... -> General -> Project)
  2. Create three folders in this project: hibernate, dependencies, hsqldb
  3. Go to the SpringSource Bundle Repository and download the following OSGi bundles:
    file save in folder
    com.springsource.org.hibernate-3.2.6.ga.jar library.target/hibernate
    com.springsource.org.apache.commons.logging-1.1.1.jar library.target/dependencies
    com.springsource.org.dom4j-1.6.1.jar library.target/dependencies
    com.springsource.org.apache.commons.collections-3.2.0.jar library.target/dependencies
    com.springsource.javax.transaction-1.1.0.jar library.target/dependencies
    com.springsource.antlr-2.7.7.jar library.target/dependencies
    com.springsource.org.hsqldb-1.8.0.9.jar library.target/hsqldb
  4. Create a new target definition library.target in this project (File -> New -> Other... -> Plug-in Development -> Target Definition)
  5. Open the target definition and add the three directories to it's contents. As the GUI does not allow you to work with relative paths, you might consider to use a text editor to paste the following text:
    <?xml version="1.0" encoding="UTF-8"?>
    <?pde version="3.5"?>
    <target description="Teneo-related stuff, mostly Hibernate" name="Library Target Definition">
        <locations>
            <location path="${eclipse_home}" type="Profile"/>
            <location path="${workspace_loc}/library.target/hibernate" type="Directory"/>
            <location path="${workspace_loc}/library.target/dependencies" type="Directory"/>
            <location path="${workspace_loc}/library.target/hsqldb" type="Directory"/>
        </locations>
    </target>
  6. Open the target definition in the Target Definition Editor and click on the Set as Target Platform hyperlink in the upper right area. This will activate the target definition. All contained bundles are now available and can be referenced as dependencies.

Create a model for your data
The data model will be based on the well-known library tutorial that ships with EMF. If you are interested in a more in-depth look, I recommend taking this tutorial. However, to shortcut things, here is the ultra-slim version of the EMF-Tutorial:

  1. Download the Rose class model and save it on your computer
  2. Create a new EMF project (File -> New -> Other... -> Eclipse Modeling Framework -> EMF Project)
    • Project name: library
    • Model importer: Rose class model
    • Browse to the Rose class model library.mdl mentioned before
    • Click on Load to load the model
    • Click Next, then Finish
  3. In the library.genmodel editor, right-click on the Library node and select Generate Model Code

Create the library main application
In order to demonstrate how to use the data model and how to perform CRUD operations with your data, we will create a simple Java class. In the good spirit of encapsulation and components, we will create a new plug-in project to host this class:

  1. Create a new Plug-in project library.main (File -> New -> Project... -> Plug-in Project)
  2. Open the manifest and add the following dependencies:
    • library (this is the bundle which contains our data model)
    • org.eclipse.emf.teneo.hibernate
    • org.eclipse.emf.ecore.xmi
    • com.springsource.org.hibernate
    • com.springsource.org.apache.commons.logging
    • com.springsource.org.dom4j
    • com.springsource.org.apache.commons.collections
    • com.springsource.javax.transaction
    • com.springsource.antlr
    • com.springsource.org.hsqldb
  3. Create a new Hibernate configuration file hibernate.properties in library.main/src and paste the following lines:
    hibernate.connection.driver_class=org.hsqldb.jdbcDriver
    # use the following line to run the embedded db:
    # hibernate.connection.url=jdbc:hsqldb:file:/some/path/on/your/computer/dbname
    # the following line will connect to a standalone (local) DB server:
    hibernate.connection.url=jdbc:hsqldb:hsql://127.0.0.1/library
    hibernate.connection.username=sa
    hibernate.connection.password=
    hibernate.dialect=org.hibernate.dialect.HSQLDialect
    hibernate.hbm2ddl.auto=true

Implement the library main application
With all the boilerplate in place, we're finally ready to write some code. We will create a new class and add some code to create an author and his book and store both in a library.

  1. Create a new class LibraryDemo, making sure it has a main method
  2. In order to use Teneo to persist our data, we first need to create a datastore and register our model package with it:
        // create the data store
        String dataStoreName = "LibraryDataStore";
        HbDataStore dataStore = HbHelper.INSTANCE.createRegisterDataStore(dataStoreName);
    
        // register the model package with the data store
        dataStore.setEPackages(new EPackage[] { LibraryPackage.eINSTANCE });
    
        // initialize the data store, which creates the tables
        dataStore.initialize();
  3. Next, we need to get hold of a session factory and request a new session form it:
        SessionFactory sessionFactory = dataStore.getSessionFactory();
        {
            Session session = sessionFactory.openSession();
            session.beginTransaction();
  4. Now, let's create a new library and save it to the session:
            // create a library
            Library library = LibraryFactory.eINSTANCE.createLibrary();
            library.setName("Developer's bookshelf");
    
            // store the library
            session.save(library);
  5. In the following part, we will create an author and his book, link them to each other and add them to the library. There is no specific Teneo aspect to this part of the code, it is just straightforward usage of the API EMF generated for your datamodel:
            // create an author
            Writer writer = LibraryFactory.eINSTANCE.createWriter();
            writer.setName("A. K. Dewdney");
    
            // create a book
            Book book = LibraryFactory.eINSTANCE.createBook();
            book.setTitle("The New Turing Omnibus");
            book.setPages(480);
            book.setCategory(BookCategory.MYSTERY); // oh well, let's hope it's not mystery to most readers!
            book.setAuthor(writer);
    
            // add book and writer to library
            library.getBooks().add(book);
            library.getWriters().add(writer);
  6. Finally, we need to commit our changes to the database and close the session:
            // commit changes to the database and close the session
            session.getTransaction().commit();
            session.close();
        }

Start the DB server and run the application

  1. Open a command line and navigate to the directory that contains hsqldb.jar
  2. Start the HSQLDB server using this command line:
    java -cp com.springsource.org.hsqldb-1.8.0.9.jar org.hsqldb.Server -database.0 file:library -dbname.0 library
  3. Finally (!) go back to Eclipse and start LibraryDemo. You should get an output similar to this one:
    Mar 6, 2009 1:50:26 PM org.eclipse.emf.teneo.hibernate.HbHelper createRegisterDataStore
    INFO: Creating emf data store and registering it under name: LibraryDataStore
    ...
    Mar 6, 2009 1:50:28 PM org.hibernate.tool.hbm2ddl.SchemaUpdate execute
    INFO: schema update complete
  4. To actually see the data stored in the database, navigate to the directory containing the database and open library.log:
    CREATE USER SA PASSWORD "" ADMIN
    /*C1*/SET SCHEMA PUBLIC
    CONNECT USER SA
    ...
    INSERT INTO "library" VALUES(1,'Library',0,'Developer''s bookshelf')
    INSERT INTO "writer" VALUES(1,'Writer',0,'A. K. Dewdney',NULL,NULL,'Library','1',-2)
    INSERT INTO "book" VALUES(1,'Book',0,'The New Turing Omnibus',480,'Mystery',1,NULL,NULL,'Library','1',-3)
    DELETE FROM "writer" WHERE E_ID=1
    INSERT INTO "writer" VALUES(1,'Writer',0,'A. K. Dewdney',1,0,'Library','1',-2)
    DELETE FROM "book" WHERE E_ID=1
    INSERT INTO "book" VALUES(1,'Book',0,'The New Turing Omnibus',480,'Mystery',1,1,0,'Library','1',-3)
    INSERT INTO "writer_books" VALUES(1,1,0)
    COMMIT
    DISCONNECT

In the next installment, I will show you how to retrieve objects from the database and query the database using Hibernate Query Language (HQL).

Download the source
If you are interested in the source for the solution so far, you can download it here: (click to download).

Thanks for reading this post. Follow me on twitter here to be notified about updates and other posts I write. Or, subscribe to my RSS feed here

Fork me on GitHub
Read more from Eclipse, Eclipse FAQ, EMF, MDSD
  • http://blogbysud.blogspot.com sud

    Love it! Short, simple, to the point and gets the job done. No need to dig through a 5 part tutorial to see how these technologies can be used together.

    Thanks.

  • http://www.peterfriese.de Peter

    Glad you liked it! Thanks for commenting!

  • Jon

    Very nice sample and explanation. I thought Hibernate needed “Eclipse-BuddyPolicy: registered”, but the com.springsource.org.hibernate does not have this in the MANIFEST.MF. Is this no longer a requirement for using Hibernate in an OSGi container such as Equinox?

  • Peter

    This is certainly good to know, but Peter I would like to ask you one question:
    Do you thing that EMF is a good choise? I am asking because to me the EMF seems to be very complicated, generated code is really a mess and most importantly the generated code looks like pre Java 5.0 code with int constants etc….. This is not a rant, but if you compare JEE and EMF style of code the difference is really big in favor of JEE.
    So are there any alternatives ?

  • http://www.peterfriese.de Peter

    Peter,
    let me address your questions.
    1) “Is EMF complicated?” – It is no more complex than any other sufficiently powerful technology. Hibernate, Spring, Struts, JSF all are sufficiently powerful and complex, so if you managed to learn these technologies you should be having no problem in learning EMF. Of course, you’ll have to invest a bit of time to learn it – but this is no different from learning any other technology.

    2) “Generated code is a mess” – I don’t know about which generator you are talking, but as far as I am concerned I haven’t seen messy generated code in years. All code generators I know (e.g. EMF, openArchitectureWare and AndroMDA) generate clean and readable code and their development teams pride themselves of generating well-formatted (and well-understandable) code.

    3) “Pre Java 5, using integer constants” – EMF is tuned for ultimate performance. Using integer constants is faster than using Enums.

    4) “Big difference between EMF and JEE code” – This is really interesting, as there is no such thing as a JEE blueprint (any more). The JEE space features such an enormous range of frameworks that you probably cannot find any two JEE applications that use the same set of technologies. So, you really need to be more precise here. Are you thinking of Spring code?

    5) “Are there any alternatives?” – Sure, there are plenty alternatives. You could for example use openArchitectureWare to generate any code you like. So, if you intend to use Spring and Hibernate in your application, you could write some code templates that generate Spring / Hibernate code from your models. See the Fornax platform for pre-built openArchitectureWare generators for this set of technologies.

  • Renat Zubairov

    Thank you for the very nice example!
    Would be interesting to know what do you think about different approaches in modifying the model – one via Session (a hibernate way) and another through the ResourceSet. Do you see any issues with that? Would you expect for example issues that are related to multi-threaded access or 1-st/2-nd level cache and object identity issues?

  • Andrew McVeigh

    Hi Peter,

    Thanks for the article.

    For my own project, I wrote a EMF-JDO mapping several years ago. The main issue was that EMF seemed to often need to do a reverse lookup in memory for things like deletes etc. This placed heavy constraints on my architecture at the time, so I rejigged the deletion etc not to require this.

    Do you know if this is still the case? How does Teneo solve this problem?

    Cheers,

    Andrew

  • http://www.peterfriese.de/using-teneo-emf-and-hibernate-to-update-and-query-your-data/ Using Teneo, EMF and Hibernate to update and query your data – Peter Friese

    [...] 2008 « Using Teneo and EMF to store your dataMost of you know that I am working as a committer for various Eclipse-related projects (such as [...]

  • http://www.elver.org Martin Taal

    Hi Peter,
    Nice blog! always feels good when people take a good look at Teneo.

    gr. Martin

  • http://www.elver.org Martin Taal

    Hi Renat,
    With Teneo you can control the hibernate session which is used by a resource. So a resource can have its own session or share sessions with other resources. The concurrency issues are the same as with other multi-user access solutions.
    I my work, I prefer the direct hibernate data access approach much more than going through resources/resourceset. For me resources always seem more targeted to hierarchical structures as XML/XMI than to the often more ‘flat’ structures in relational databases. But this ofcourse depends on the case.

    gr. Martin

  • http://www.elver.org Martin Taal

    Hi Andrew,
    Yes EMF has some really specific behavior related to bi-directional relations and resource handling. As orm’s like hibernate also take care of both sides of a bidirectional association this requires some special attention. Teneo handles this by making use of some detailed EMF api to update only one side of a bidirectional relation so that this is done without side-effects (such as sending out notifications).

    gr. Martin

  • Daniele fanì

    Hi Peter,
    thanks for the tutorial. I have a problem.
    I would create the database each time a create an object “library”, and each time I add an object on the canvas, i would add it to the database. So the idea is to put the creation of the database in the method “createLibrary” of the LibraryFactory. I can’t understand why it doesn’t work. It gives me no error, but at the line

    "HbDataStore dataStore = HbHelper.INSTANCE.createRegisterDataStore(dataStoreName);"

    stop to work anything.
    Hope in your help. Many thanks.

    Daniele

  • Daniele fanì

    [UPDATE]

    with a try-catch , i saw that it stops because give the exception
    java.lang.NoClassDefFoundError: org/hibernate/SessionFactory

    I imported all the needed library and updated the manifest…. why can’t find it at runtime?

  • aappddeevv

    Is there any documentation or best practices for using EMF Teneo Hibernate Spring?

    With just Spring and Hibernate, there is a variety of direct spring support that I find useful but I don’t know what the design patterns are for using the HbDataStore and its affinity for placing inside a container.

  • Svetlio

    Hello.

    I have followed your tutorial but I get very annoying exception:

    SEVERE: JDBC Driver class not found: com.mysql.jdbc.Driver
    java.lang.ClassNotFoundException: com.mysql.jdbc.Driver
    at org.eclipse.osgi.internal.loader.BundleLoader.findClassInternal(BundleLoader.java:489)

    I tried with org.hsqldb.jdbcDriver but the result is the same. I have downloaded the required bundles from http://www.springsource.com/repository/app/ and they are started successfully.
    I also tried to remove com.springsource.* bundles from my target platform, download hibernate and mysql jars, put them in new plugin and export all packages but this didn’t help too. With this approach I was getting ClassNotFoundException for some hibernate class…

    Have you experienced such a problems? Do u have suggestions?

    Thank you!

    Regards,
    Svetlio

  • Carrol McFayden

    Pity you didn’t make your own example, instead just paraphrased the standard IBM example. There is too much of this going on.

  • http://www.peterfriese.de Peter Friese

    Thanks for your comment. Back when I created this tutorial, there weren’t any easy-to-follow, reproducible tutorials. A friend of mine asked me a number of questions regarding Teneo, so I decided to help him and potentially others by writing up this tutorial.

  • xxxxxih

    “In order to keep things simple, we “…pfffff :D
    When I used EMF 2 years ago, nothing was simple and working with it was a nightmare. The most simple things took ages and some thing were only possible by understanding parts of emf (JET,…) without usable documentation. I was tempted for a short second to give it a try again. But thanks to this article I got convinced that nothing has changed… the simplest things take ages. And sorry, I don’t see where the “powerful” is.

  • http://www.peterfriese.de Peter Friese

    Thanks or your comment, which made me smile. As stated in a previous comment, if you managed to learn to use frameworks like Struts, JSF, Hibernate and the like, you shouldn’t have a problem learning EMF. Like anything powerful, it takes some to learn. BTW, I guess you had to practice quite a bit to learn to ride a bike, didn’t you ;-)

  • Adomas

    Can you readd source code? Now link is broken.

  • Samy

    I tried your demo directly on my already existing model and it worked straight away.
    Thank you very much for this concise tutorial.

  • http://www.register-web-domain.in Domain registration

    Nice articles …I am very happy to read this article..Thanks for giving
    us nice info. Fantastic walk-through. I appreciate this post.

  • http://www.register-web-domain.in Domain registration

    Nice
    articles …I am very happy to read this article..Thanks for giving
    us nice info. Fantastic walk-through. I appreciate this post.

  • http://www.register-web-domain.in Domain registration

    Nice
    articles …I am very happy to read this article..Thanks for giving
    us nice info. Fantastic walk-through. I appreciate this post.