Tuesday 17 June 2014

A Hibernate Environment Implementation bug in Netbeans

Some database, e.g., HSqlDB, can be opened in file mode. In such mode, the database is occupied by the open process only. The Netbeans plug-in of Hibernate cannot map database object to Hibernate ORM file through "Hibernate Reverse Engineering Wizard" when using such database and opening in such mode refer to below screen copy.



Netbeans will issue an error message of "Cannot establish direct database connection". Check the log file of Hibernate. The stack trace shows an Exception from the method of canDirectlyConnectToDB method in class of HibernateEnvironmentImpl.

Here is the code snippet that lead to the problem,

     ccl = getProjectClassLoader(getProjectClassPath().toArray(new URL[]{}));
            Thread.currentThread().setContextClassLoader(ccl);
            HibernateUtil.getDirectDBConnection(config);
            logger.info("Direct Database connection established.");
            Thread.currentThread().setContextClassLoader(originalClassLoader);
            return true;
    } catch (Exception e) {
            logger.log(Level.INFO, "Cannot establish direct database connection", e);
    } finally
......
 The plugin does not call C3P0 connection pool to test the connection but call DirectDBConnection again. It leads to the dead lock on database file finally.

To fix the bug and do not wait plug-in project team, we need to change the source code and re-comile the jar file java\modules\org-netbeans-modules-hibernate.jar. However, there is a short time work-round to modify the class file in the jar directly by JAVA Byte Code Editor.

Locate the class file in the jar and extract it and make a backup copy. Then after opening the class file with Byte Code Editor, below compiled code can be shown in the tab of "Code Editor" method mentioned.


 Change it to:
invokestatic org/netbeans/modules/hibernate/util/HibernateUtil/getDBConnection(Lorg/netbeans/modules/hibernate/cfg/model/HibernateConfiguration;)Lorg/netbeans/api/db/explorer/DatabaseConnection; 

Save the class file and replace it in the jar. It shall be good to go.

No comments: