Red Hat



In Relation To Max Andersen

In Relation To Max Andersen

Hibernate Tools Demo at EclipseCon

Posted by    |       |    Tagged as

I'll be demo'ing Hibernate Tools at EclipseCon on March 21st. See details here .

It is a 15 minute demo, so will be a quick'n'dirty presentation; but it will give you a good insight on what is available via the plugins currently and what is coming .

Koen Aers will also be presenting A Gentle Introduction to GEF which is used in the basis of the jBPM designer which can be used to model business processes and pageflow for JBoss Seam .

Marshall Culpepper is also present thus the core team behind JBoss Eclipse IDE will be there.

A story about FreeMarker and Velocity

Posted by    |       |    Tagged as Java EE

I have been fed up with Velocity ís ability to ignore and even hide errors and exceptions occurring in the templates used in Hibernate Tools .

This blog tells about why and how FreeMarker became my new interest. If you just want to see the results then go and fetch the code in the TOOLS_FREEMARKER branch...read on to get the full story.

The problems with Velocity

I started to see more and more forum postings and bug reports about issues that were caused by typoís in users templates or even worse errors in the Hibernate Tools. Many of these issues would be solvable within seconds if Velocity would actually tell where in the templates the error occurred and unit tests would have failed if underlying exceptions were exposed; but Velocity simply does not.

I have added every safety-precaution I have been able to apply to Velocity error handling. I have created my own UberSpect and EventHandler implementation that will not allow you to invoke methods that does not exist and I have tweaked the logging settings to be more informative; but it does not (hardly) solve all the problems that can occur.

Logging is excessive in Velocity even at WARN and INFO level, one good reason for this is most likely that the developers know that Velocity is ignoring situations where it should actually fail, thus since there is no easy other way implemented in Velocity they put it in the log for users to discover by accident!

The choice originally fell on Velocity since it was the biggest player around, and I added it naively thinking that the error and log handling could not be that bad if so many people were using it and if there were an issue it would be fixed soon.

As time went by I learned that it was definitely not the case.

The beauty of FreeMarker

Last week I decided to look around for alternatives, the only real alternative I found were FreeMarker; everything else looked either too simple or way to complex for the Hibernate Tools needs. Now that I have spent just 1,5 day converting the existing Velocity templates to FreeMarker Iím more than happy I did.

Here are some examples of the beauty of FreeMarker:

Assume we have the following bean:

public class Table {
 String getName();
}

The bean is available via table in the following code:

${table.namee}

That typo will just be ignored by default in Velocity, with a custom EventHandler it can be convinced to throw an exception which comes out like this:

Caused by: java.lang.IllegalArgumentException: $table.namee is not a valid reference.
at org.hibernate.tool.hbm2x.HibernateEventHandler.referenceInsert([=>HibernateEventHandler.java:11])
        at org.apache.velocity.app.event.EventCartridge.referenceInsert([=>EventCartridge.java:131])
        ... 19 more

No information about which template nor where in the temmplate it went wrong.

In FreeMarker I get the following with no special configuration and custom code:

Expression table.namee is undefined on line 15, column 14 in doc/tables/table.ftl.
The problematic instruction:
----------
==> ${table.namee} [on line 15, column 12 in doc/tables/table.ftl]
----------

Java backtrace for programmers:
----------
freemarker.core.InvalidReferenceException: 
 Expression table.namee is undefined on line 15, column 14 in doc/tables/table.ftl.
    at freemarker.core.TemplateObject.assertNonNull([=>TemplateObject.java:124])
    at freemarker.core.Expression.getStringValue([=>Expression.java:118])
    at freemarker.core.Expression.getStringValue([=>Expression.java:93])
    ...

Nice! And even better, the on line 15, ... works like a link in e.g. Eclipse Console view. Clicking it brings you to the location of the error in the table.ftl. file.

Similar and precise error messages you get if you refer to non existing methods, Just brilliant! The great thing is that if I really wanted FreeMarker to ignore this I could do so by installing a different Exception handler. But that is my choice, not a hard to change behavior.

The built in primitives in FreeMarker is also great, e.g. <#assign> that allows me to store any generated output in a variable for later usage.

${pojo.getPackageDeclaration()}
// Generated ${date} by Hibernate Tools ${version}
<#assign classbody>
 <#include "PojoTypeDeclaration.ftl"/> {
  ..more template code..
 }
</#assign>

${pojo.generateImports()}
${classbody}

This allows me to remove the need to have a magically second-pass which I did with Velocity. There are more gems like these to be found in the excellent FreeMarker documentation .

Another big plus in FreeMarker's favor is the Configuration API . Let us compare, here is our Velocity setup:

engine = new VelocityEngine();
context = new VelocityContext();

EventCartridge ec = new EventCartridge();
ec.addEventHandler(new HibernateEventHandler()); // stricter evaluation
ec.attachToContext( context );
            
Properties p = new Properties();
p.setProperty(RuntimeConstants.RUNTIME_LOG_LOGSYSTEM_CLASS, 
              "org.apache.velocity.tools.generic.log.CommonsLogLogSystem");
p.setProperty(CommonsLogLogSystem.LOGSYSTEM_COMMONS_LOG_NAME, 
              "org.hibernate.tool.hbm2x.template");

p.setProperty( RuntimeConstants.UBERSPECT_CLASSNAME, HibernateUberspect.class.getName() ); // stricter evaluation

p.setProperty("velocimacro.library",""); // make it shut up about VM_global_library blah
      
p.setProperty("resource.loader", "file, class");
p.setProperty("file.resource.loader.path", directory );
p.setProperty("class.resource.loader.class", ClasspathResourceLoader.class.getName() );

engine.init(p);

Here is the corresponding FreeMarker config:

engine = new Configuration();
context = new SimpleHash(ObjectWrapper.BEANS_WRAPPER);

//Logger.setCategoryPrefix("org.hibernate.tool.hbm2x.template"); 
// Not really needed since the logging is much more sensible.

freeMarkerEngine.setTemplateLoader(new MultiTemplateLoader( 
                                    new FileTemplateLoader(directory), 
                                    new ClassTemplateLoader(this.getClass(),"/"));

Notice the difference? FreeMarker has good practice defaults and actually allows me to use java code to configure it; what a neat concept.

The only two bad things I have found yet with FreeMarker is that itís syntax is based on <#..> which does not compute very well when trying to show it in an XML editor. This has been fixed in the latest release by also allowing [#...] syntax.

Another bigger issue is that ${} and #{} is not escapable. This syntax collides in templates that generates ant build and jsp files.

In Velocity they were just ignored (the only place were it were useful to ignore them). FreeMarker complains because the values are undefined and unfortunately there is no easy-on-the-eyes method to escape these characters. The following show the methods that I found to allow the me to output ${..}:

${r"${build.dir}"}  
${'$í}{build.dir} 
<#noescape>${build.dir}</noescape>

Still the brilliant exception handling, powerful template language and configuration API makes FreeMarker a much better choice for Hibernate Tools.

What now ?

Velocity served me well and is probably serving many projects well; it just did not cut it well for Hibernate Tools. Today I am convinced that I could have saved myself and the Hibernate world from a lot of trouble if I had decided to use FreeMarker from the beginning.

Come and see for your self in the TOOLS_FREEMARKER branch. The code in there will be merged into the main development in the near future unless someone steps up with a very good reason for not doing so ;)

To be fair, I must tell you that Velocity 1.5 is being worked on right now, and it does seem to solve some of these issues, but not completely and Velocity has some external dependencies I would rather not add to the tools project.

Hibernate Tools 3.1 Beta 4 released

Posted by    |       |    Tagged as

A new updated version of the Hibernate Tools (http://tools.hibernate.org) project have been made available.

The tools are for both Eclipse and ANT. In this release the documentation for both ANT and Eclipse have been extensively updated and merged into a reference documentation, see http://www.hibernate.org/hib_docs/tools/reference/en/html_single/

See screenshots and other noteworthy news at http://www.hibernate.org/hib_docs/tools/eclipse/newandnoteworthy/hibernate-eclipse-news-3.1.0.beta4.html for more information.

As always feedback, ideas, contributions, patches, bug-reports are more than welcome by the usual means at http://forum.hibernate.org and JIRA.

Currently we are discussing wether FreeMarker should replace the current Velocity template engine used in the tools or if something can be done to make the Velocity templates more userfriendly. Come and join at http://forum.hibernate.org/viewtopic.php?t=954602

Hibernate 3.1: Reduced wiring code needed for native sql

Posted by    |       |    Tagged as Hibernate ORM

Over the past few months we have been adding some simplifications to the way you can use and specify native sql queries in Hibernate. Gavin even blogged about some of them earlier , but I thought it were about time we brought some more news on this blog about it.

Auto detect return types and aliases

The newest feature related to native sql is that Hibernate will now auto detect the return types and even aliases of any scalar value from a sql query.

Before you had to do something like:

List l = s.createSQLQuery("SELECT emp.regionCode as region, emp.empid as id, {employee.*} 
                           FROM EMPLOYMENT emp, EMPLOYEE employee ...")
         .addScalar("region", Hibernate.STRING)
         .addScalar("id", Hibernate.LONG)
         .addEntity("employee", Employee.class)
         .list();
Object[] data = l.get(0);

Today you do not need to specify the type of the scalar values, but simply the alias name so Hibernate knows what data you actually want to extract from the resultset.

List l = s.createSQLQuery("SELECT emp.regionCode as region, emp.empid as id, {employee.*} 
                           FROM EMPLOYMENT emp, EMPLOYEE employee ...")
         .addScalar("region")
         .addScalar("id")
         .addEntity("employee", Employee.class)
         .list();
Object[] data = l.get(0); 

If the query is only returning scalar values then addScalar is not needed at all; you just call list() on the query.

List l = s.createSQLQuery("SELECT * FROM EMPLOYMENT emp").list();
Object[] data = l.get(0); 

It of course needs some more processing from Hibernate, but it makes experimentation and some data processing problems easier to do.

No redundant column mappings

Previously when you specified native sql in named queries you had to use the return-property element to (redundantly) specify which column aliases you wanted Hibernate to use for your native sql query. It were redundant because in most cases you would simply just be specifying the exact same columns as you had just done in the class mapping.

Thus it could get pretty ugly and verbose when you were starting to have even just mildly complex mappings such as the following which is from our unit tests for a native sql stored procedure call.

<sql-query name="selectAllEmployees" callable="true">
 <return alias="employement" class="Employment">
 <return-property name="employee" column="EMPLOYEE"/>
 <return-property name="employer" column="EMPLOYER"/>                     
 <return-property name="startDate" column="STARTDATE"/>
 <return-property name="endDate" column="ENDDATE"/>                       
   <return-property name="regionCode" column="REGIONCODE"/>                       
   <return-property name="id" column="EMPID"/>                                            
   <return-property name="salary"> 
    <return-column name="VALUE"/>
    <return-column name="CURRENCY"/>                      
   </return-property>
 </return>
 { call selectAllEmployments() }
</sql-query>

In the upcoming Hibernate 3.1 you can do the exact same with loss less code:

<sql-query name="selectAllEmployees" callable="true">
 <return class="Employment"/>
 { call selectAllEmployments() }
</sql-query>

or in code (for normal sql):

List l = s.createSQLQuery("SELECT * FROM EMPLOYMENT emp")
          .addEntity(Employee.class)
          .list();
Object[] data = l.get(0); 

This also removes the need for always using the curly brackets syntax (e.g. {emp.name})to handle the aliasing as long as you are not returning the same entity type more than once per row.

Hope you like it, Enjoy :-)

Pop Quiz: Does Connection.close() result in commit or rollback ?

Posted by    |       |    Tagged as

Earlier today I saw a transaction question targeted for a completely different audience pop up as the first headline news item on a well known java news site. Besides giving me and my colleagues a good laugh about bugs and transactions it also touched upon one of the questions that have given me a couple of free beers in bar bets and been mind-boggling for students during trainings. The question relates to the following (simplified) code:

Connection con = DriverManager.getConnection(url, name, pwd);
con.setAutoCommit(false);
Statement st = con.prepareStatement("delete VITAL_DATA");
st.executeUpdate();
con.close();

Assuming that VITAL_DATA contains data before we execute this code, will it still contain those data after the call to con.close()?

Yes or No ?

The answer is: It depends!

If this code were executed against an Oracle database VITAL_DATA will no longer contain data since Oracle implicitly calls commit() if your connection has left over changes.

It is about here people starts arguing with me and say I'm crazy! No way that is possible, because all developers who believe in the goodness of transactions and its ACID properties would state that nothing should be committed to a database without an explicit call to commit() when not running in auto-commit mode - anything else would be a sin.

Well, I guess Oracle like to be sinful, and it is even documented.

/Page 3-14, Oracle9i JDBC Developers Guide and Reference/ contains the following text:

If auto-commit mode is disabled and you close the connection
without explicitly committing or rolling back your last changes,
then an implicit <code>COMMIT</code> operation is executed.

I heard from an Oracle tech-guy that this behavior is a left over from how the old OCI library worked - whether that is true or not I don't know; but it sure is a surprise for most developers I have shown this too (including my self the first time I bumped into this issue).

After discovering this a couple of years back I went to look in the JDBC spec to see who is to blame for this behavior.

The fun part is that I have not been able to find anything about the behavior of close() in JDBC besides the following text from the /JDBC 4.0/ spec:

When auto-commit is disabled, each transaction must be explicitly committed by
calling the Connection method commit or explicitly rolled back by calling the
Connection method rollback, respectively.

The javadoc for close() states:

Releases this Connection object's database and JDBC resources
immediately instead of waiting for them to be automatically released

From a naive ACID believing person I would say Oracle are wrong on this, but notice how the specification only mentions how the transaction behaves ? It does not explicitly state that close() is not allowed to commit the data, only that it should release resources (which it does!)

Thus from my perspective Oracle is walking on an edge here, but apparently without breaking the spec. Note that it might also occur on other databases, but it has never occurred for me on the other major databases I have worked with.

Lessons learned ? Always explicitly (or declaratively) commit or rollback your transactions!

Hibernate Tools 3.1 Beta 1 released

Posted by    |       |    Tagged as

A new updated version of the Hibernate Tools (http://tools.hibernate.org) project have been made available.

The tools are for both Eclipse and ANT, the ANT related docs are at http://www.hibernate.org/hib_docs/tools/ant/index.html

The biggest new feature is that you can now use your annotated classes in the query console (require JDK 5) and thus be able to prototype EJB3 queries.

We also added support for named parameters in the query console making it very easy to test existing queries from your application since you do not need to replace the parameters with inplace values.

See the screenshots and other noteworthy news at http://www.hibernate.org/hib_docs/tools/eclipse/newandnoteworthy/hibernate-eclipse-news-3.1.0.beta1.html for more information.

As always feedback, ideas, contributions, patches, bug-reports are more than welcome by the usual means at http://forum.hibernate.org and JIRA.

Hibernate Tools Alpha 5 released

Posted by    |       |    Tagged as

A new updated version of the Hibernate Tools (http://tools.hibernate.org) project have been made available.

The tools are for both Eclipse and ANT, the ANT related docs are at http://www.hibernate.org/hib_docs/tools/ant/index.html

The eclipse plugins is now compatible with WTP 0.7 and contains a bunch of new features and improvements.

My personal favorite at the moment, is the Dynamic Query Translator view which continously shows you the SQL, Hibernate will generate for the query you are typing in the HQL editor. Great for learning and tuning HQL queries - note that EJB3-QL works here too.

The HQL editor is also new and replaces the HQL view and introduces code formatting, syntax highlighting and code completion.

Furthermore we have a initial class diagram view as well as many other improvements to wizards, templates, and code generators. See the complete list with screenshots at class diagrams at http://www.hibernate.org/hib_docs/tools/newandnoteworthy/hibernate-eclipse-news-3.1.0.alpha5.html for more information.

As always feedback, ideas, contributions, patches, bug-reports are more than welcome by the usual means at http://forum.hibernate.org and JIRA.

Hibernate Tools Alpha 4 released

Posted by    |       |    Tagged as

The new updated version of the Hibernate Tools (http://tools.hibernate.org) project includes significant updates to the Eclipse editors, plugings, and wizards, as well as a unified and convenient Ant task for integration of the tools in your regular builds.

See http://www.hibernate.org/hib_docs/tools/newandnoteworthy/hibernate-eclipse-news-3.0.0.alpha4.html for a visual mini-tour of the new features.

Ant task documentation is at http://www.hibernate.org/hib_docs/tools/ant/index.html

Java Webstart enabling Hibern8IDE - no luck!

Posted by    |       |    Tagged as

Recently I have been messing with adding custom class loading to Hibern8IDE, so it can load model and database driver classes at dynamically.

This allows us to run Hibern8IDE standalone instead of requiring users to run it from their actual project (which of course still is possible ;)

The 'trick' is as follows:

Thread thread = Thread.currentThread();
ClassLoader prevCl = thread.getContextClassLoader();
   try {
       List urls = ... // a list of paths/zips/jars for the classloader
       if(urls.size()>0) {
            URLClassLoader _newLoader = new URLClassLoader((URL[]) urls.toArray(new URL[0]), thread.getContextClassLoader());
            thread.setContextClassLoader(_newLoader);
            }                   
        // convince DriverManager that you can use our specified driver!
        String driverClass = props.getProperty("hibernate.connection.driver_class");
        if(driverClass!=null) {
        try {
            Class driverClazz = ReflectHelper.classForName(driverClass);
            DriverManager.registerDriver(new FakeDelegatingDriver((Driver) driverClazz.newInstance()));
            } catch (... e1) {               
            }
        }
        configuration = new Configuration();
        configuration = configuration.setProperties(props);
        configuration = configuration.configure(configfile);
        
        Iterator hbms = mappings.iterator();
        
        while (hbms.hasNext()) {
            hbm = (File) hbms.next();
            configuration = configuration.addFile(hbm.toString());
         }
         
         initialize(); // build sessionfactory etc.
        } catch (... e) {
       } finally {
        thread.setContextClassLoader(prevCl);
       }

The code does two things install Hibern8IDE custom classloader while loading the mappings and jdbc drivers PLUS install a FakeDelegatingDriver to convince the stupid java.sql.DriverManager that it is ok to load jdbc drivers from other places than the system classloader.

And this works!, but not when trying to Java Webstart enabling Hibern8IDE :(

It seems like Java Webstart is very strict about it's permission policy even though a <all-permission/> tag are in the JNLP file :(

The loading of model classes and drivers works smoothly, but as soon as the driver wants to connect to the database a security exception is throwing saying the application is not allowed to connect to a port on the database machine :(

So, for now Hibern8IDE is available in a standalone version, but unfortunately not via Java Webstart because of it's strictness!

Any bright ideas are welcome!

Not so Naked Objects

Posted by    |       |    Tagged as

Currently I have noticed that Naked Objects gets more and more blog-time. And every time I wondered why (many?) people found it so intriguing - and I often thought about making a blog about the good and bad about Naked Objects; but I've never found the time.

I still don't have the time to do a detailed blog about it, but just state some facts and/or criticism about the implementation of Naked Objects that I've can't remember seeing listed before.

A. All objects has to implement NakedObject or extend AbstractNakedObject (actually some code in the framework assumes every object is an AbstractNakedObject...but that I guess they will fix a some point).

B. All fields that you want the framework to know about need to be a NakedValue, thus String has to be a TextString, float a FloatingPointNumber, etc. This is all basically done to let the values be mutable and add all the linguistic needs for their (all to easy to criticize, so I won't) automatic GUI.

C. All collections of associated objects need to be NakedCollection which definitly is not in any way a standard java.util.Collection (because they also do not use anything from jdk 1.2, just to be able to run on .Net!).

Each of point A, B and C makes me not like the Naked Objects framework (at least the implementation)! Why ? Because all my objects won't be POJO's anymore - and especially item C, makes it very hard to e.g. use Hibernate (or many other reflection based ORM's) to persist these not so Naked Objects. It at least require some very specific Naked Object code to make it work.

And when we are talking about persistence, then the whole framework does have a built-in persistence engine which is pluggable - but it's very simple, and transaction demarcation looks very hard to control, if even possible at the moment.

But enough harsh criticism ;), the good stuff is their ideas about behavioral complete objects (BCO). From the book: an object should completely model the behavior of the thing that it represents. ... most people continue to design business systems that separate procedure from data, albeit dressed up in the language and technology of object-orientation.

And I do agree to that point - people do get to procedural at times, myself included, and if Naked Objects help us do that a little less I would appreciate it.

Their automatic (and empowering to the users as they call it) UI, is somewhat interesting - but geez, they seriously got to look more into ui design ;) (and yes, I know they did look into ui design to empower their users, but I simply don't think their UI has value in other areas besides being provocative and different ;)

And as I understand the authors then it is the BCO and the automatic created UI that is their focal point, but I don't understand why they have not utilized existing technologies that is close to almost do the same....like the JavaBeans API ? JavaBeans is more than just a naming standard for properties! It was build for allowing IDE's to inspect objects and build intelligent UI's!

It got an Introspection API which one could use to discover all the details of an object and the API is extensible in a much more non-intrusive way than Naked Object does it.

What about using standard property listeners ? Why limit you to use jdk 1.1 ? Who want's to only use Vector, and why not utilize the Collections API interfaces to make their object structure much more standard compliant ?

In the end I encourage the authors to work on their core concepts: BCO and automatic UI's (even though I don't think it will cover more than a few useful applications). But they should really look into using more JDK API's for this, so the framework becomes more useful in real-life applications.

P.S. And why is their catch all blocks and printStackTrace() multiple places in the source of a system that candidates for being used in more than just prototype systems ?

back to top