Jump to: navigation, search

Teneo/Hibernate/QuickStart

< Teneo‎ | Hibernate
Revision as of 01:02, 29 November 2012 by Mtaal.elver.org (Talk | contribs)

(diff) ← Older revision | Latest revision (diff) | Newer revision → (diff)

This quick start shows how EMF, Teneo and Hibernate work together to automatically creates the database schema and persist EMF objects.

The quick start tutorial uses the example project which you can download here.

This tutorial assumes some basic knowledge of EMF. If you are new to EMF then it can make sense to first try one of the core EMF tutorials which you can find here.

Initial Setup

The quick start assumes that you have a running Eclipse with EMF and Teneo installed. In addition the Teneo dependencies (incl. hsqldb and mysql drivers) should be installed. See the Download & Install page for more information.

The quick start uses hsqldb but it can easily be changed to use mysql or another database. For other databases than hsqldb and mysql you need to take make sure that the jdbc driver is in the classpath of the org.eclipse.emf.teneo.hibernate.examples project.

For mysql and other non-in-memory databases you have to create the database up-front (so not the tables inside the database but just the database itself). For the quick start the database name should be: library.

Running 'quick start'

After downloading the examples project from cvs you can directly run the quick start program. Open the project and navigate to the QuickStart.java file and right click and select 'Run As > Java Application'. You will see several things getting printed to the console (one of them is the generated Hibernate mapping).

This run takes the following steps:

  • reads the EPackage model from the generated EPackage file.
  • generate a hibernate mapping for the EPackage
  • create the database (on hsqldb)
  • create EMF objects and persist them

Walk-through

Now let's walk through the code of the quick start to understand what it does. There are two distinct phases: 1) initialization and 2) runtime. Teneo is called/used explicitly in the initialization phase. In the runtime phase you will see that you only use EMF and Hibernate.

Initialization

The code starts with setting hibernate database connection properties:

// The hibernate properties can be set by having a hibernate.properties file in the root of
// the classpath.
// Another approach is setting the properties in the HbDataStore.
// For more information see section 3.1 of the Hibernate manual
final Properties props = new Properties();
props.setProperty(Environment.DRIVER, "org.hsqldb.jdbcDriver");
props.setProperty(Environment.USER, "sa");
props.setProperty(Environment.URL, "jdbc:hsqldb:mem:library");
props.setProperty(Environment.PASS, "");
props.setProperty(Environment.DIALECT, org.hibernate.dialect.HSQLDialect.class.getName());

Teneo supports many configuration options which control the mapping and runtime behavior. The quick start shows an example on how to set one:

Note: the above configuration uses the hsqldb in-memory storage, if you use the hsqldb file storage, don't forget to add this code before closing the session:

session.createSQLQuery("SHUTDOWN").executeUpdate();

Otherwise nothing gets written to the file system.

// set a specific option
// see this page http://wiki.eclipse.org/Teneo/Hibernate/Configuration_Options
// for all the available options
props.setProperty(PersistenceOptions.CASCADE_POLICY_ON_NON_CONTAINMENT, "REFRESH,PERSIST,MERGE");

Then a datastore is created. A datastore controls the persistence of one or more EPackages. In addition the properties defined above are set in the store.

// the name of the session factory
String hbName = "Library";
// create the HbDataStore using the name
final HbDataStore hbds = HbHelper.INSTANCE.createRegisterDataStore(hbName);
 
// set the properties
hbds.setDataStoreProperties(props);

As a next step the EPackages are set and the datastore is initialized:

// sets its epackages stored in this datastore
hbds.setEPackages(new EPackage[] { ExtlibraryPackage.eINSTANCE });
 
// initialize, also creates the database tables
try {
	hbds.initialize();
} finally {
	// print the generated mapping
	System.err.println(hbds.getMappingXML());			
}

This initialization step maps the EPackages to hibernate and creates the database schema. The generated hibernate mapping is printed to the console.

As a last initializiation step the Hibernate SessionFactory is created:

SessionFactory sessionFactory = hbds.getSessionFactory();

Runtime

At runtime first a Hibernate Session is created. Then the Library is instantiated and persisted:

// Create a session and a transaction
Session session = sessionFactory.openSession();
Transaction tx = session.getTransaction();
 
// Start a transaction, create a library and make it persistent
tx.begin();
Library lib = ExtlibraryFactory.eINSTANCE.createLibrary();
lib.setName("My Library");
session.save(lib);

Then in the next steps a Book and Writer is created and the transaction is committed:

// create a writer
Writer writer = ExtlibraryFactory.eINSTANCE.createWriter();
writer.setName("JRR Tolkien");
 
// and one of his books
Book book = ExtlibraryFactory.eINSTANCE.createBook();
book.setAuthor(writer);
book.setPages(305);
book.setTitle("The Hobbit");
book.setCategory(BookCategory.SCIENCE_FICTION);
session.save(book);
 
// add the writer/book to the library. The writer and book are automatically
// made persistent because they are added to the library which is already
// made persistent
lib.getWriters().add(writer);
lib.getBooks().add(book);
 
// at commit the objects will be present in the database
tx.commit();
// and close of, this should actually be done in a finally block
session.close();

When you now check your database you will see that tables got created and the above objects have been persisted:


Org.eclipse.emf.teneo.quick.tutorial.db.png


Next tutorials will show how to read the information from the database.

Try some changes

You can try out mysql or another database by changing the properties in the beginning of the quick start:

		props.setProperty(Environment.DRIVER, "com.mysql.jdbc.Driver");
		props.setProperty(Environment.USER, "root");
		props.setProperty(Environment.URL, "jdbc:mysql://127.0.0.1:3306/" + dbName);
		props.setProperty(Environment.PASS, "root");
		props.setProperty(Environment.DIALECT, org.hibernate.dialect.MySQL5InnoDBDialect.class.getName());

Make sure that the jdbc driver is in the classpath and that the database (called library) is created before running the quick start.

As a next step you can change the ecore model and regenerate the model code and re-run the quick start. You will see the changes reflected in the database schema.