Wednesday, December 29, 2010

Persisting EMF Objects to RDBMS with Teneo and Hibernate

In my project, EMF Objects are now being persisted in a CDO Model Repository. It used to use "plain Teneo", but before scraping the code I'd like to share it in my blog so in case I want to use Teneo directly again I won't be in trouble. ;-)

Teneo is a way to persist EMF Objects in a relational database using Hibernate and JPA annotations (you can also use EclipseLink, but I think Hibernate is better supported by Teneo).

JPA annotations are generated automatically by Teneo but you can configure the JPA mapping/annotations manually by using Teneo's JPA model annotations (not JPA Java annotations) on the EMF metamodel.

Connecting to the Hibernate EMF Data Store

private void initHibernate() {
// Set the database information, Environment is org.hibernate.cfg.Environment
final Properties props = new Properties();

// props.setProperty(Environment.DRIVER, "org.hsqldb.jdbcDriver");
// props.setProperty(Environment.USER, "sa");
// //props.setProperty(Environment.URL, "jdbc:hsqldb:file:/tmp/hsqldb");
// props.setProperty(Environment.URL, "jdbc:hsqldb:mem:abispulsamodel");
// props.setProperty(Environment.PASS, "");
// props.setProperty(Environment.DIALECT, org.hibernate.dialect.HSQLDialect.class.getName());
props.setProperty(Environment.DRIVER, "com.mysql.jdbc.Driver");
props.setProperty(Environment.USER, "root");
props.setProperty(Environment.URL, "jdbc:mysql://127.0.0.1:3306/abispulsamodel");
props.setProperty(Environment.PASS, "");
props.setProperty(Environment.DIALECT, MySQLInnoDBDialect.class.getName());
// Set cascade policy for containment and non-containment references
props.setProperty(PersistenceOptions.CASCADE_POLICY_ON_CONTAINMENT, "ALL");
props.setProperty(PersistenceOptions.CASCADE_POLICY_ON_NON_CONTAINMENT,
  "MERGE,PERSIST,REFRESH");

// Create and register the datastore, it will be accessible using
// this EMF Resource URI: hibernate://?dsname=abispulsa
hbds = HbHelper.INSTANCE.createRegisterDataStore("abispulsa");
// Set the EPackages that will be used with this data store
hbds.setEPackages(new EPackage[]{AbispulsaPackage.eINSTANCE});
hbds.setProperties(props);
hbds.initialize();
}

Note: the above syntax is for Teneo 1.1.2. For Teneo 1.2.0, setProperties() becomes setDataStoreProperties().

As you can see, configuring data store properties is just like with "plain" Hibernate.

You can change the DBMS backend easily by simply changing a few lines.
And of course you can externalize the configuration to a .properties file or .xml or whatever suits you best.

Using the Hibernate EMF Resource

Simple load:

HibernateResource resource = new HibernateResource(URI.createURI("hibernate://?dsname=abispulsa"));
resource.load(null);

Load with query, get specific EMF Object classes:
HibernateResource resource = new HibernateResource(
  URI.createURI("hibernate://?dsname=abispulsa&query1=FROM Organization"));
resource.load(null);

After you have a Resource, it's pretty much standard EMF / Resource stuff from here just like regular XMI-based resources.

"Copy and paste" (aka import) EMF Objects from an XMI file to Hibernate Resource:

ResourceSet rset = new ResourceSetImpl();
Resource xmiResource = rset.createResource(URI.createFileURI("/path/to/model/Catalog.xmi"));
try {
xmiResource.load(null);
log.info("XMI Resource has " + xmiResource.getContents().size() + " objects.");
for (EObject obj : xmiResource.getContents()) {
log.info(obj.toString());
}
Collection<EObject> copies = EcoreUtil.copyAll(xmiResource.getContents());
resource.getContents().addAll( copies );
resource.save(null);
} catch (Exception e) {
log.error("Error", e);
throw new RuntimeException(e);
}

Each time you open a Hibernate resource, a new Hibernate session is created by Teneo, which is fine for most purposes.

But you can change this by using your own session manager for Teneo.

Disconnecting from the Data Store

void closeHibernate() {
if (hbds != null) {
hbds.close();
HbHelper.INSTANCE.deRegisterDataStore(hbds);
hbds = null;
}
}

Comparison with CDO

With CDO it's almost the same, but with CDO there's a need to explicitly openTransaction() before editing objects in a CDO resource.

After manipulating a resource, either resource.save() or transaction.commit() will persist the changes.

Connect to CDO Server
private static final String CONNECTION_ADDRESS = "tcp://localhost:2036";
private static final String REPO_NAME = "abispulsabisnis";
...
log.info("Connecting to CDO to {} using repo {}", CONNECTION_ADDRESS, REPO_NAME);
org.eclipse.net4j.connector.IConnector connector = Net4jUtil.getConnector(IPluginContainer.INSTANCE, CONNECTION_ADDRESS);
// Create configuration
org.eclipse.emf.cdo.net4j.CDOSessionConfiguration sessionConfiguration = CDONet4jUtil.createSessionConfiguration();
sessionConfiguration.setConnector(connector);
sessionConfiguration.setRepositoryName(REPO_NAME);
org.eclipse.emf.cdo.session.CDOSession session = sessionConfiguration.openSession();
session.getPackageRegistry().putEPackage(AbispulsaPackage.eINSTANCE);

CDO is designed to be used over a network using TCP connector. But it's possible to run the CDO server and CDO client on the same VM instance, and a JVM Net4j connector is provided.

Open a Resource
org.eclipse.emf.cdo.transaction.CDOTransaction transaction = session.openTransaction();
org.eclipse.emf.cdo.eresource.CDOResource resource = transaction.getResource("/organization");

Save Changes
try {
//resource.save(null); // You can also do this (non-CDO aware)
transaction.commit(); // or this (CDO-aware)
} catch (Exception e) {
...
}

Update: As CDO committer Eike Stepper points out, CDO's resource.save() simply delegates to the underlying CDO Transaction's commit().

Close CDO Session
session.close();

That's it! I originally wanted to cover only Teneo but you got CDO Crash Course as a bonus. ;-)

15 comments:

  1. Hi Hendy,

    In CDO you don't need resource.save(null); It just delegates to commit() of the associated transaction.

    Cheers
    /Eike

    ReplyDelete
  2. @Eike Thanks! I just noticed that. The Resource.save() support is good for non-CDO aware classes to be able to commit without know CDO transaction.

    I like that :)

    ReplyDelete
  3. We've made an EMF item style Cheap RS Goldproduced from XML schema. I can change the idea and also increase brand-new qualities and also include brand-new child aspects for the subject design. On the other hand can't add wording articles to the items which will become feasible in line Sell Runescape Goldwith the schema.

    ReplyDelete
  4. i enjoy your producing ,its therefore understandable ,pleasant and easy you just read .. thx . Cheap RS money
    Cheap Guild Wars 2 Gold

    ReplyDelete
  5. Thanks for all your nice explanation, hope for more...

    Fast delivery + 15% Discount can be assured if you buy buy runescape gold pay by Western Union on Rsorder!

    Details at: http://www.rsorder.com/profile/news/read/id/448

    Free 200M runescape gold Giveaway on RSorder Flash Sale!

    Time: 03:00 AM on December 21, 2012 GMT

    To know more: http://www.rsorder.com/profile/news/read/id/441

    ReplyDelete
  6. With patch 1.0.7 coming soon, the price of cheap diablo 3 gold will definitely rise. Players are currently hurry to accumulate cheap diablo 3 gold . Now, a good news for all diablo iii players: Diablohome Free 100000K D3 Gold Giveaway for Newsletter Subscribers begins. Hurry to snap free diablo 3 gold.
    More tags : D3 Gold Diablo 3 Gold buy D3 Gold

    ReplyDelete
  7. Microsoft Project 2010 Download includes a timeline view that is automatically displayed above other views, showing a concise overview of the entire schedule. You can add tasks to the timeline and even print it for an attractive summary report of the entire project. Or you can paste it into an e-mail for an instant report with no fuss.
    Adobe Acrobat 9 Pro Download includes Adobe LiveCycle Designer ES software for advanced form creation.

    ReplyDelete
  8. Here we have 5% Extra Gold Coupon Code:"rsgoldfast.com"for you
    Exp.date:Jan.10th.2016

    ReplyDelete
  9. I want to import/Export data using XML in CDO DB. I do not want the code. I just want to know the way it is performed in CDO DB. Can anyone provide me an abstract summary of this?
    It will be a huge help. Thank you!

    ReplyDelete
  10. The best store to buy Madden coins online: GameMS. Every Madden player needs to confirm the security and price when buying Madden coins. GameMS has a long history and rich experience in trading EA game currency, which can ensure the security of your transactions and personal information. Providing the industry's lowest prices and high-quality customer service is your best choice.

    ReplyDelete
  11. Buy the most popular MMORPG game Path of Exile Currency, POECurrency.com is the best partner on the Path of Exile, buy POE currency on poecurrency.com, you will experience the most professional trading services, we are the best trading website in the industry.

    ReplyDelete
  12. Sometimes whenever a certain color doesn't flatter how you wish bridesmaid dresses did, it features a lot to do using the contrast between that color and the colour of hair. To reduce this variable within the equation of the bad color match, consider using a hairdo that pulls hair back tightly. This will draw less attention towards the clash between hair color as well as your black bridesmaid dresses color.

    ReplyDelete