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
- Get Eclipse 3.5 M5 (click here to download)
- Unpack and start Eclipse
- Bring up the “Install New Software” dialog (Help -> Install New Software)
- Select Teneo EMF Hibernate Runtime and Teneo EMF Hibernate SDK, version 1.0.3
- Cick Finish
- 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.
- Create a new project library.target (File -> New -> Project… -> General -> Project)
- Create three folders in this project: hibernate, dependencies, hsqldb
- 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 - Create a new target definition library.target in this project (File -> New -> Other… -> Plug-in Development -> Target Definition)
- 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> - 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:
- Download the Rose class model and save it on your computer
- 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
- 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:
- Create a new Plug-in project library.main (File -> New -> Project… -> Plug-in Project)
- 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
- 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.
- Create a new class LibraryDemo, making sure it has a main method
- 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(); - 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(); - 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); - 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); - 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
- Open a command line and navigate to the directory that contains hsqldb.jar
- 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
- 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
- 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. If you want to get in touch with me, use the contact form.






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.
Glad you liked it! Thanks for commenting!
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?
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 ?
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.
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?
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
[...] 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 [...]
Hi Peter,
Nice blog! always feels good when people take a good look at Teneo.
gr. Martin
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
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
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
[UPDATE]
with a try-catch , i saw that it stops because give the exception
java.lang.NoClassDefFoundError: org/hibernate/SessionFactoryI imported all the needed library and updated the manifest…. why can’t find it at runtime?
hi Peter!
I think I have the same problem like Daniele. I try the example in the same way you described, but I got that error message after starting the LibraryDemo.java
02.11.2010 17:14:29 org.eclipse.emf.teneo.hibernate.HbHelper createRegisterDataStore
INFO: Creating emf data store and registering it under name: LibraryDataStore
Exception in thread “main” java.lang.NoClassDefFoundError: org/hibernate/EntityNameResolver
at org.eclipse.emf.teneo.hibernate.HbHelper$1.createHbDataStore(HbHelper.java:60)
at org.eclipse.emf.teneo.hibernate.HbHelper.createRegisterDataStore(HbHelper.java:162)
at library.main.LibraryDemo.main(LibraryDemo.java:21)
Caused by: java.lang.ClassNotFoundException: org.hibernate.EntityNameResolver
at java.net.URLClassLoader$1.run(Unknown Source)
at java.security.AccessController.doPrivileged(Native Method)
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
… 3 more
anyone an idea whats going wrong there? thanks for any help!
bye sebastian
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.
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
Pity you didn’t make your own example, instead just paraphrased the standard IBM example. There is too much of this going on.
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.
“In order to keep things simple, we “…pfffff
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.
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
Can you readd source code? Now link is broken.
Hi… thanks for the nice explanation…
I have two questions:
How EMF and Teneo deal with ID’s/keys. Should I do some special in ecore model?
Teneo will use the model annotated OCL for anything?
thanks
I tried your demo directly on my already existing model and it worked straight away.
Thank you very much for this concise tutorial.
Nice articles …I am very happy to read this article..Thanks for giving
us nice info. Fantastic walk-through. I appreciate this post.
Nice
articles …I am very happy to read this article..Thanks for giving
us nice info. Fantastic walk-through. I appreciate this post.
Nice
articles …I am very happy to read this article..Thanks for giving
us nice info. Fantastic walk-through. I appreciate this post.