-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 
Author Message
 Post subject: Dynamic ORM with Hibernate 3.3.1, a few questions
PostPosted: Mon Jun 01, 2009 6:15 am 
Beginner
Beginner

Joined: Mon Jun 01, 2009 5:39 am
Posts: 34
Hello everyone,

As the subject says, I'm in the process of creating such a beast. As such, I have two session factories, unlike what is usually recommended, but it's a necessity here.

The first one is dedicated to accessing, and modifying, the object definitions (a POJO mapped to a simple two columns table, one with the entity name, the other with the contents of the Hibernate mapping file). I then use the stored definitions to rebuild the second session factory.

This second session factory is therefore dynamically updated. I spawn sessions with either dynamic-map mode or dom4j mode. The user never sees Hibernate sessions directly, instead I spawn an object from which it can do its stuff (getting the object list, getting an object template to fill, listing objects, writing objects). The object is created with its creation date as a field, and as such I can detect whether the configuration (and therefore the session factory) has been updated in the meanwhile, and proceed only if the template it uses is valid (object exists, its editable fields haven't changed, etc). This is what I use to rebuild the configuration (wlock is the writeLock() or a ReentrantReadWriteLock, persistor has all mappings "pre-digested"):

Code:
      final Configuration newcfg
         = new Configuration().addProperties(defaultProperties);

      wlock.lock();
      try {
         for (final String mapping : persistor.getMappings())
            newcfg.addXML(mapping);
         newcfg.buildMappings();
         cfg = newcfg;
         sf = cfg.buildSessionFactory();
         ObjectCache.reset(cfg);
         lastModified = new Date();
      } catch (Exception e) {
         throw new InvalidMappingException(
            "Failed to reload configuration! Keeping old one", e
         );
      } finally {
         wlock.unlock();
      }


I can add and remove mappings, and when I regenerate the session factory, Hibernate updates the tables for me, so far so good. But it doesn't delete tables, however. Is there a way to get the DDL from Hibernate to delete a table?

Also, I haven't played yet with "multiple column fields" or even foreign keys. Here is how I detect what fields can be edited, what fields are compulsory. So far, it works, but is there a better way?

Code:
// Here we have:
//   r = cfg.getClassMapping(objectName).getRootClass();
//

// Constructor - descriptor is an org.dom4j.Document
   public ObjectDescriptor(final RootClass r)
   {
      descriptor = DocumentHelper.createDocument();

      final Element e = descriptor.addElement("object");

      e.addAttribute("name", r.getEntityName());

      e.add(createField(r.getIdentifierProperty()));

      @SuppressWarnings("unchecked")
      final Iterator<Property> i = r.getPropertyIterator();

      while (i.hasNext())
         e.add(createField(i.next()));
   }

// The createField() method
   private Element createField(final Property p)
   {
      final Element result = DocumentHelper.createElement("field");

      result.addAttribute("name", p.getName());

      final Element
         optional = result.addElement("optional"),
         editable = result.addElement("editable"),
         type = result.addElement("type");

      optional.setText(Boolean.toString(p.isOptional()));

      type.setText(p.getType().getName());

      editable.setText("true");

      final Value v = p.getValue();

      if (v.isSimpleValue()) {
         final SimpleValue sv = (SimpleValue) v;

         if (sv.getIdentifierGeneratorProperties() != null)
            editable.setText("false");
      }

      return result;
   }


Thanks,


Top
 Profile  
 
 Post subject: Re: Dynamic ORM with Hibernate 3.3.1, a few questions
PostPosted: Mon Jun 01, 2009 4:56 pm 
Beginner
Beginner

Joined: Mon Jun 01, 2009 5:39 am
Posts: 34
Reply to self...

Hibernate's hbm2ddl is not stateful, since SessionFactories are not, so I used a workaround:

Code:
   private void doDDLDrop(final String mapping)
      throws HibernateException
   {
      final Configuration cfg = new Configuration()
         .setProperties(defaultProperties);

      final Dialect d = Dialect.getDialect(defaultProperties);

      cfg.addXML(mapping);
      cfg.buildMappings();

      final String[] queries = cfg.generateDropSchemaScript(d);

      final Session s = factory.openSession();
      final Transaction tx = s.beginTransaction();
      try {
         for (final String ddlQuery: queries) {
            logger.debug("Executing DDL: \"{}\"", ddlQuery);
            final Query q = s.createSQLQuery(ddlQuery);
            q.executeUpdate();
         }
         tx.commit();
      } catch (HibernateException e) {
         tx.rollback();
         throw e;
      } finally {
         s.close();
      }
   }


And it works :)

But I have learned about the more general SchemaUpdate object, which can ease the process further.


Top
 Profile  
 
 Post subject: Re: Dynamic ORM with Hibernate 3.3.1, a few questions
PostPosted: Fri Jun 12, 2009 10:00 am 
Beginner
Beginner

Joined: Wed Nov 05, 2003 7:51 am
Posts: 22
Looks like an interesting project, Hibernate lacks dynamic mapping behaviour.

This is especially bad for modularized applications since you need to build a huge SessionFactory at application start (with all of the classes of the application) instead of being able to add classes only when they are actually needed.

Keep us posted, I would be very happy to use a Hibernate-variant which is capable of dynamically accepting new persistent classes in a SessionFactory !!!


Top
 Profile  
 
 Post subject: Re: Dynamic ORM with Hibernate 3.3.1, a few questions
PostPosted: Fri Jun 12, 2009 5:41 pm 
Beginner
Beginner

Joined: Mon Jun 01, 2009 5:39 am
Posts: 34
Hello, and thanks for your interest ;)

I have to say, though, that I don't use POJOs, I use the dynamic-map and dom4j entity modes only. Using classes would require a class generator which I just don't know how to program at all (Hibernate does this, I know, but I don't know either where or how - I'm just not ready to dive into that code, since POJO is not my priority).

Apart from the POJO side, I'm making progress. The core is coded and tested, but lacks some fundamental stuff due to Hibernate's lack of DDL capabilities (Hibernate cannot add an index to an existing column, for one; I have spotted other limitations, too, which I'm working on fixing). I also have an HQL query generator from XML which works but is far from being complete.

When I get to a fully functional prototype, I'll publish it, but it WILL require patches to Hibernate itself, I just cannot achieve what I really want without modifying Hibernate's Dialect...


Top
 Profile  
 
 Post subject: Re: Dynamic ORM with Hibernate 3.3.1, a few questions
PostPosted: Sat Jun 13, 2009 4:09 am 
Beginner
Beginner

Joined: Wed Nov 05, 2003 7:51 am
Posts: 22
Hibernate's SchemaUpdate and SchemaExport have a LOT of limitations, I don't recommend using them. They are suggested for development only anyway, not for production databases.

We use Liquibase XML changesets for DDL management, which is a nice, database-independent schema transformation management tool.
We write the schema creation and schema update scripts manually for absolute control.

You may generate the changesets according to your dynamic model and execute them with an embedded Liquibase instance.


Top
 Profile  
 
 Post subject: Re: Dynamic ORM with Hibernate 3.3.1, a few questions
PostPosted: Mon Jun 22, 2009 5:06 pm 
Beginner
Beginner

Joined: Fri Jun 29, 2007 2:19 pm
Posts: 26
Location: Fremont, CA
good work fge,
Looks very interesting, In fact we can use something like this in our project right now. Do you know how soon you would be have this available? Integrated liquibase would be cool for DDL.

-Shailesh

_________________
-shailesh


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 6 posts ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.