Red Hat

In Relation To Emmanuel Bernard

In Relation To Emmanuel Bernard

Using Abstraction frameworks to maintain control? Wrong bet.

Posted by    |       |    Tagged as

I've seen lot's of people writing (or using) third party abstraction frameworks on top of ORM solutions like Hibernate so that they can potentially get rid of one ORM engine to another (or even an other technology). Such frameworks are even considered by some architectsas a must-have.

Praiseworthy, but raising more issues than fixing ones. When you abstract technologies like Hibernate to make them portable, you end up sacrificing lot's of power and functionalities. Simply because semantics are slightly different from one engine to an other.

Let's play with statistics:

  • in 1% of the applications, the need for a switch from one ORM engine to an other arise
  • in 99% of the applications, the need for one or several advanced features of ORM arise

You should focus on using and knowing your ORM engine and not on spending time in writing (or using) an abstraction framework.

When using abstraction frameworks you haven't written, other kind of problems actually show up.

When your ORM engine introduce new APIs or new features, you have to wait for the abstraction framework to release accordingly making you dependent on someone else's agenda.

You no longer know (either by heart or at all) the actual method abstraction (or semantic alteration) introduced on top of your ORM engine. This user learnt it the hard way (and he is unfortunately not alone), Spring's /HibernateTemplate/ wraps the Hibernate methods without even giving you a hint about the actual semantic.

The only proper abstraction between an ORM engine and another is a common specification they adhere to. This is one of the reasons why JPA (EJB 3.0) has been introduced. Why is it the only way? Because a specification describes in a very detailed way the common semantic the various ORM engines have to follow.

So please, think twice before using some random proprietary abstraction framework (open source or not). They usually bring no value add but increasing bug areas... Specifications are here to solve the engine abstraction problem (but once again, this is a concern in very few applications).

PS in case someone is misleading, I'm not arguing against DAO layers

Never been that close to Java Persistence compliance

Posted by    |       |    Tagged as Java EE

EJB3 XML mapping files

The latest release of Hibernate EntityManager (3.1.0 beta8) now support EJB3 XML mapping files (aka deployment descriptors). While annotations are considered a huge step forward for development ease-of-use and productivity, some folks out there stayed concerned about the ability to split metadata from the code. This is now supported in Hibernate Annotations (3.1.0 beta 10) and Hibernate EntityManager in a standard manner. You can partially overrides java annotations or you can write all you metadata through XML. The easiest solution is to add META-INF/orm.xml in your ejb-jar or persistence jar. This file is automatically taken into account by the persistence provider. Alternatively you can add a <mapping-file/> element to your persistence.xml file. Here is a sample for EJB3 XML file

<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings xmlns="[=>http://java.sun.com/xml/ns/persistence/orm]"
               [=>xmlns:xsi=]"=>http://www.w3.org/2001/XMLSchema-instance"
               [=>xsi:schemaLocation=]"=>http://java.sun.com/xml/ns/persistence/orm orm_1_0.xsd"
               version="1.0">
  <package>org.hibernate.test</package>
  <entity class="Car" metadata-complete="true" access="PROPERTY">
      <table name="CARS"/>
      <named-query name="carsByManufacturer">
          <query>select c from Car c where c.manufacturer = :manufacturer</query>
          <hint name="org.hibernate.timeout" value="200"/>
      </named-query>
      <attributes>
          <id name="id">
              <generated-value strategy="AUTO"/>
              <column name="car_id"/>
          </id>
          <basic name="category" optional="false">
              <enumerated>STRING</enumerated>
          </basic>
          <many-to-one name="manufacturer">
              <join-column name="manufacturer_fk"/>
          </one-to-many>
      </attributes>
  </entity>
</entity-mappings>

Glassfish integration

I have been working with the Glassfish team for some times now to make sure Hibernate EntityManager integrates well with Glassfish. Now that the specification has been frozen, the integration is working very smoothly:

  • download Hibernate Core (for HEM 3.1.0 beta 8, you will need Hibernate 3.2 CR1)
  • copy the required hibernate (and third party libs) into $glassfish_home/lib
  • adjust your persistence.xml file to use Hibernate EntityManager
<persistence version="1.0">
    <persistence-unit name="pu">
        <provider>org.hibernate.ejb.HibernatePersistence</provider>
        <!-- JNDI name of the database resource to use -->
        <jta-data-source>jdbc/sqlserver</jta-data-source>
        <properties>
            <!-- drop and create tables at deployment if needed -->
            <property name="hibernate.hbm2ddl.auto" value="create-drop"/>
        </properties>
    </persistence-unit>
</persistence>

That's it! Glassfish sets the appropriate Transaction Manager Strategy and Hibernate can guess the appropriate Dialect for most common databases.

Hibernate EntityManager is know to run in all up-to-date EJB3 implementations. Of course, it runs smoothly in JBoss EJB3 and JBoss Embeddable EJB3 .

Mapping of Maps

This has been a long time requested feature, it is now available, you can map you associations using Map<Element, ...> or Map<Embeddable, ...> using an explicit key column(s)

The Hibernate team is please to announce Hibernate EntityManager 3.1beta6 and Hibernate Annotations 3.1beta8, a compliant implementation of the latest and greatest EJB3 Proposed Final Draft.

What's new in the spec and in Hibernate's implementation:

  • cleaner way to persist enums
  • enhancement round queries including support for scalar and composite primary keys in native queries
  • implicit entity access type depending on the @Id annotation position
  • callbacks and entity listeners inheritance in an entity hierarchy
  • more natural annotation design (better separation of concern for some features)
  • possibility to have mapped superclasses or even non mapped superclasses in between two entities in the hierarchy
  • support for long conversation programmatic model
  • enhanced locking API
  • multiple persistence unit declaration per jar file
  • possibility to disable entities autodiscovery in jar files
  • .par extension no longer needed

Check it out

Hibernate 3.1.1 released

Posted by    |       |    Tagged as Hibernate ORM

Hibernate 3.1.1 has been released earlier this week. This maintenance release focused on bugfixes and improvements, especially regarding:

  • SQL Server support
  • DML-style HQL (UPDATE, DELETE, INSERT INTO... SELECT)
  • Native Query support
  • Connection handling

For details check out the release notes

Hibernate 3.1 introduced non OLTP features as well as better environment integration:

  • Custom strategy for session handling through CurrentSessionContext including 2 default implementations (JTA based and ThreadLocal based session handling)
  • more natural and aggressive connection handling in J2EE and J2SE environments
  • command-oriented API (StatelessSession API) for operations on huge number of objects
  • bulk UPDATE, DELETE, INSERT INTO ... SELECT for multi table entities
  • extra lazy collections for huge collection handling
  • use of join fetch on collection through scrollable resultsets through break processing
  • database generated properties (including database timestamps)
  • additional ON clauses for joins
  • dirty checking short-cuts for instrumented classes

Downloads are available here

par-tition your application

Posted by    |       |    Tagged as

Packaging has always been a manual operation in ORM world. In Hibernate, you have to list the mapped entities either through the configuration API or through the hibernate.cfg.xml file. For a while now, JBoss AS has introduced the notion of .har, basically an archive scanned by the deployer to discover the Hibernate configuration and the hbm.xml files in it.

Packaging inside an EJB3 container

The EJB3 expert group has introduced the same notion in the EJB3 public draft. A PAR archive is basically a jar file having the .par extension. All you have to do is put all your annotated entities in the archive and the container has the responsibility to scan it and find all annotated entities. A PAR archive is a persistence unit definition that will be used to create an EntityManagerFactory (aka SessionFactory in the Hibernate world). You will then be able to use your persistence unit (by looking up or injecting an EntityManager or an EntityManagerFactory) named by the name of the PAR file without the extension (ie mypersistenceunit.par will be referred as mypersistenceunit).

Since you might want to customize your persistence unit configuration, a persistence.xml file can be added in the META-INF directory.

<?xml version="1.0" encoding="UTF-8"?>
<entity-manager>
   <name>FinancialPU</name>
   <provider>org.hibernate.ejb.HibernatePersistence</provider>
   <jta-data-source>jdbc/MyDB</jta-data-source>
   <class>com.acme.MyClass</class>
   <jar-file>externalEntities.jar</jar-file>
   <properties>
       <property name="hibernate.max_fetch_depth" value="4"/>
   </properties>
</entity-manager>

Let's analyze this small but comprehensive example.

The name element allows you to override the persistence unit name (defaulted to the PAR file name minor the .par suffix).

The provider element allows you to express the Entity Manager implementation you want to use for this persistence unit. The value is defaulted to Hibernate Entity Manager if none is specified. This is a interesting one, this basically means that you can use several Entity Manager implementations in the same application or use the Hibernate Entity Manager implementation in lieu of your vendor EJB3 persistence implementation in a standard way!

The jta-data-source aside with the non-jta-data-source let you specify the datasource the persistence unit will work onto.

The class element, allows you to add explicitly some entities to be mapped. These entities are typically outside of the PAR archive and the Entity Manager will search them in the EAR classpath. This is particularly convenient to be able to share the same entity definition across several persistence unit.

The jar-file element, allows you to ask the entity manager implementation to add all the entities contained in a particular JAR and include them in the configuration. In the case of the Hibernate Entity Manager, it will also look at the hbm.xml files. This is particularly convenient to share a certain amount of entities definitions across several persistence units.

There is also a mapping-file element currently not supported in Hibernate Entity Manager's implementation.

The properties elements is a way to provide some implementation specific properties to your entity manager. In the case of Hibernate you can add most of the hibernate.* properties. You can also define the second level cache informations using hibernate.ejb.classcache.* and hibernate.ejb.collectioncache.*, please refer to the reference documentation for more information.

This is good news for JBoss users, the .har archive is now standardized. The packaging that has always been a strong concept in J2EE is now extended to the ORM world in a very ease of use manner.

Packaging in J2SE environment

The very new point is that the PAR packaging simplicity works in the exact same manner in the J2SE world. The only difference is that you'll need to define your datasource not through the jta-data-source element but through the classic hibernate.* connection properties. The PAR archive is still scanned to find its contained entities and hbm.xml files. In order to let the Hibernate Entity Manager discover the PAR files, they need to have a persistence.xml file in the META-INF directory (Hibernate Entity Manager basically request any resources named META-INF/persistence.xml and deduces the PAR archive location from it).

Let's imagine the following acmedomainmodel.par archive structure

com/acme/model/Animal.class (an @Entity annotated class)
com/acme/model/Dog.class (an @Entity annotated class)
com/acme/model/Cat.class (an @Entity annotated class)
com/acme/model/Customer.class (a non annotated POJO)
com/acme/model/Customer.hbm.xml (the metadata definitions of Customer)
META-INF/persistence.xml

where persistence.xml is

<?xml version="1.0" encoding="UTF-8"?>
<entity-manager>
   <properties>
       <property name="hibernate.max_fetch_depth" value="4"/>
       <property name="hibernate.dialect" value="org.hibernate.dialect.MySQLInnoDBDialect"/>
       <property name="hibernate.connection.driver_class" value="com.mysql.jdbc.Driver"/>
       <property name="hibernate.connection.username" value="emmanuel"/>
       <property name="hibernate.connection.password" value="secret"/>
       <property name="hibernate.connection.url" value="[=>jdbc:mysql:///test]"/>
       <property name="hibernate.cache.provider_class" value="org.hibernate.cache.EhCacheProvider"/>
   </properties>
</entity-manager>

My persistence unit named acmedomainmodel will then contains automatically Animal, Dog, Cat, Customer. Note that the Customer class don't really have to be in the PAR archive, it just need to be in the classpath as long as its hbm.xml definition itself is inside the PAR archive.

Note that you can tune the discovery mechanism through the hibernate.ejb.autodetection. The possible values are none (no auto detection), class (auto detection of the annotated entities), hbm (auto detection of the hbm files) and class,hbm (auto detection of both annotated entities and hbm files).

With a simple ant task you can then create a PAR archive which contains automatically your persistent domain model. No need to manually add the mapped entities inside the hibernate.cfg.xml file anymore.

Several persistent unit in my application

You can of course use several PARs archive in your application. The appropriate PAR archive will be processed based on the name your provide.

//create a keep the emf for later entity manager creations
EntityManagerFactory emf = Persistence.createEntityManagerFactory("acmedomainmodel");
...
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
em.persist(customer);
wolfy = em.find(Dog.class, wolfyId);
em.getTransaction().commit();
em.close();

Note that if there is only one PAR archive in your classpath, you don't have to pass the name to the createEntityManagerFactory() method, but is considered good practice however.

The PAR archive mechanism offers a very convenient and standard way to package your ORM persistent units. By its autodiscovery mechanism, the packaging setting up scales in a very elegant manner.

Hibernate Entity Manager 3.1 beta 2 and Hibernate Annotations 3.1 beta 4

Posted by    |       |    Tagged as

New releases of both Hibernate Entity Manager and Hibernate Annotations are available.

Hibernate Entity Manager now supports full .par archive including entity and hbm files auto discovery (see the previous blog entry for more details on this feature) and fixes some critical bugs (see the release notes http://sourceforge.net/project/shownotes.php?release_id=346915).

Hibernate Annotations new release is focused on better support of Hibernate specific features (all Hibernate id generators support, column indexes generation, non PK referencedColumnName support for @OneToOne, @ManyToOne, and @OneToMany...) and of course bug fixes (See the release notes http://sourceforge.net/project/shownotes.php?release_id=346914 for more details).

These releases are compatible with the latest Hibernate core release (3.1 beta1).

Hibernate Annotations alpha1

Posted by    |       |    Tagged as

We just released the brand new Hibernate Annotations module as an alpha version. This module provides the Hibernate facilities to declare Hibernate O/R mapping metadata through JDK 5.0 metadata annotations (instead of XML mapping files or XDoclet preprocessing). We have implemented the EJB3 (JSR-220) O/R metadata annotations defined in the early draft 1 of the spec. This set of annotations covers all common mappings cases.

Next step for us is to provide custom annotations to cover Hibernate specific features while following the EJB3 spec evolutions.

This tool is designed for easy-of-dev and quick application development (mapping metadata in the sources, no preprocessing step, configuration by exception minimizing the metadata declarations). Give a try to this new programming model. Feedbacks are welcome, especially on the Hibernate specific features you want to see covered by annotations.

Download it and have a look at the tutorial and the comprehensive test suite. It will give some good samples.

Reattaching an object having no modification

Posted by    |       |    Tagged as

It happens sometimes that a domain model objet dettached from a previous session needs/can be reattached without trigging an UPDATE (whether it has optimistic locking or not). Hibernate supports this kind of feature by providing:

session.lock(myEntity, LockMode.NONE);

Thus, Hibernate will not propagate the modifications unless they are made after the reattachment to the session.

Don't use it as an optimization

First of all, try to avoid this feature. Usually, reattaching an object using session.saveOrUpdate() or by retrieving it through a session.get()/session.load() is fast enough for you. I'm not kidding, do not suppose it's significantly faster in your real application not to update the object (esp. when versioning is switched on) or not to retrieve it from the DB: do some benchmark before any decision.

Beware of boundaries

Associated object are not always managed the way you want. Uncascaded properties are not reattached to the session.

I am currently working on a project where some entities needs to be reattached using a lock mode NONE. In my case, the entity is a Contact. Contact is linked to some barely updated (and cached) entities. In a particular but very frequent use case, I know for sure that the Contact instance I get is the same as the DB version one. It appeared to me to be the best use case for session.lock(contact, LockMode.NONE);

Unfortunatly, the contact I retrieve is associated (but not cascaded) to some lazy loaded (at the second level of the graph) entities, so I cannot properly walk through my object graph.

The solution I've used is to redefine properly my object graph boundary, by refreshing some of the Contact properties with fresh entities.

contact = ... //get it from somewhere
session = sf.openSession();
Transaction tx = session.beginTransaction();
ContactType type = session.load( 
        ContactType.class, 
        contact.getContactType().getId() 
    );
contact.setContactType(type);
session.lock(contact, LockMode.NONE);
//work with contact safely

I'm now able to walk my graph through contact, eg:

contact.getContactType().getFavoriteChannel();

Notice several things:

  • I used load() instead of get(), it allows me to get a proxy if available and thus don't hit the DB
  • I set the refreshed property before reattaching the object to avoid useless updates.

Know what you do

This feature it quite complex because it may break the ACID semantic (contact and the other entities where not loaded in the same transaction) and may lead to very tricky issues. I did use this optimization (reduce of DB hit) because I knew my application business process very well, I was sure it won't break any data, and because it makes me gain signficant time. I have considered seriously the following solution.

session.get(Contact.class, contact.getId());

This one line of code is your friend, don't ban it too early. That's the most natural way of playing with the object.

Practical tips on JDK 1.5 annotations

Posted by    |       |    Tagged as

Maybe you haven't noticed, but every single piece of information on JDK 1.5 Metadata Annotations is nothing but a simple /Hello World/ tutorial (of course, I exclude the specification). There is no real world implementation. This is especially true for codes processing the annotations. I'll call such an application an annotation reader.

I was publicly cursing about that and Cedric Beust answered in his blog and gave me some hints.

I want to add some more tips and comments about Cedric's list, based on my experience with the development of Hibernate annotations:

  • default values, what about null?
  • faking a non-existing annotation programmatically
  • no extends, what about code duplication?

default values, what about null?

Nothing to declare, except that Cedric is right. The whole point is that there should be something that let's the annotation reader know whether the user set the value or used the default one. However, no such mechanism has been provided by the JSR.

As a workaround I've also build my own BooleanImplied enum type that takes care of values not explicitly set by the user. With Strings, I don't really like using some restricted key-string, such as #implied. For now, my special key-string works like a charm, but one day it will face the what-if-I-want-to-use-that-keyword-as-a-value syndrome. I've no better answer :-(

faking a non existing annotation programmatically

In annotation reader code, there is no way to programmatically build a new annotation /instance/, whether with or without default values. Of course, an annotation is an interface and there is no implementation provided! However, building your own annotation could be useful to keep the code as generic as possible and to fake a user provided annotation. (Especially if most of your annotations have default values).

Let's have a look at an example:

public @interface Column {
    /** 
     * column name
     * default value means the name is guessed.
     */
    String name() default "#implied";

    /**
     * column length
     * Default value 255  
     */
    int length() default 255;

    [...]
}

public @interface Property {

    /**
     * column(s) used
     * Default is guessed programmatically based on the default @Column()
     */
    Column[] columns() default {};

    [...]
}

@Property()
public String getMyProperty() {
    return myProperty;
}

I want to use the default values of @Column() when the user does not set any @Column() array in @property(). Why? Because I want the simplest annotations, I want implicit and default values to be the rule, and I don't want to duplicated my annotation processing code.

Two solutions:

  • duplicate the default values somewhere in a value holder class (don't like that one)
  • keep a fake method somewhere with the default @Column() inside:
/**
 * Get default value for annotation here
 * (I couldn't find a way to build an annotation programatically)
 */
@Column()
private static void defaultColumnAnnHolder() {}

You'll then be able to read and reuse this method in your annotation reader code. I think some bytecode manipulation framework can easily and elegantly provide such feature without the ugly extra method in your code. (Javassist 3.0 should be able to do that if I understand Bill Burke, but I've not tested it yet)

no extends, what about code duplication?

That one that really sucks. The extends keyword is not allowed for annotation. Without it, we can't build a generic method, handling an annotation hierarchy. Bye-bye to the beauty of OO.

Suppose I have @CoreProperty() and then @ComplexProperty():

public void handleProperties(CoreProperty ann) {
    [...]
}

This can't process @ComplexProperty(), as there is no way to let @ComplexProperty inherit @CoreProperty.

Some solutions:

  • force your user to set @ComplexProperty() and @CoreProperty() on its annoted method (I don't consider this as an option)
  • use composition
  • copy annotation data into a new class hierarchy (or flatten it)
  • use reflection on annotation

The second one is pretty simple but it may not be appropriate for every model:

@ComplexProperty(
    @CoreProperty(...)
)

If the CoreProperty is an implementation concept, it's pretty ugly to show that in the annotation.

The third solution kind of sucks, but that is the one I'm using now. The annotation reader has to be implemented with two layers:

  • a layer reading and flatteninng the annotation (or putting it in an extra class hierarchy)
  • a process method, handling properties in flat (or hierarchical) representation:
public void processPropertyAnn(Ann property) {
    [...]
    String name = property.name();
    processFlatProperty(name, null);
}

/**
 * Process a property
 * @param name property name
 * @param extraValue this extraValue can be set using ComplexProperty
 */
private void processFlatProperty(String name, String extraValue) {
    [...]
}

This leads to some extra metadata structure: the good old DTO are evil issue appears in annotation!

The fourth solution will probably be complex and unreadable code, it seems to me that reflection is overkill in this case (I haven't implemented it, however).

Time to conclude

Well, I stayed focused on JSR 175 practical flaws and gave some tips to make life easier. I still strongly believe annotations are good and will give us a new way of thinking metadata in our apps. I don't care which one is best: XDoclet or JSR 175, I care about a standard metadata facility (this topic is mature enough for standardization). I care about a standard metatada desription to easily plug tools on top of frameworks like Hibernate.

This spec will evolve. But for now, don't curse about it, use it for real!

back to top