Google
 
Web unafbapune.blogspot.com

Wednesday, August 31, 2005

 

Bulk Insert in Hibernate 3.0.5

Bulk insert operation is a nice feature in that a single DML such as HQL or SQL will result in zero or multiple records inserted into a table. Unfortunately, Hibernate 3.0.5 does not yet support bulk insert operation, even though both bulk update and delete operations are supported. Since bulk insert is supposed to be supported in Hibernate 3.1, so I downloaded the latest 3.1beta2 release and tried. It didn't work.

So, how can we make bulk insert operations happen in Hibernate 3.0.5 ? Well here is a quick hack. Hibernate allows parameterized native SQL Query to be specified in the Hibernate mapping file via the <sql-query> XML element. So one obvious idea is to specify a native SQL Query with an INSERT statement. However, I couldn't get this to work without tweaking two classes:
    org.hibernate.loader.Loader.java
org.hibernate.loader.custom.CustomLoader.java
The hibernate3.0.5-patched.jar can be used as a drop-in replacement of the hibernate3.jar as found in the 3.0.5 distribution.

Example:
    <sql-query name="bulkInsertQuery1">
<return-scalar column="null" type="int"/>
insert into A (a1, a2, a3)
select b1, b2, :p1 from B
where b3 = :p2
</sql-query>
  1. The <return-scalar> is necessary to keep Hibernate 3.0.5 happy, so it won't reject the insert statement.

  2. The column="null" is a special notation recognized by the patched classes to simply execute the native SQL without bothering with the return value.
Usage Sample: (Assume we are using Spring.)
    String[] paramNames = {"p1", "p2"};
Object[] paramValues = {"p1value", "p2value"};
// Execute the native SQL Query purely for it's side effect
getHibernateTemplate().findByNamedQueryAndNamedParam("bulkInsertQuery1", paramNames, paramValues);
That's all. It's a hack but it works perfectly for executing any arbitrary native SQL!

Is this the smell of wet dog ? Hopefully the Hibernate team will provide proper support for HQL bulk insert operation in the near future. As requested, this hack has been submitted as a patch.

Monday, August 08, 2005

 

Accessing Default Namespace with XPath

I was wondering if there is a way in XPath to access XML elements specified with a default namespace. For example, here is an XML using namespace "ns1" and a default namespace:

<ns1:A xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="http://hanson/Dadidadida">
xmlns:ns1="http://hanson/Dadidadida/ns1"
>
<ns1:B><C/></ns1:B>
</ns1:A>
How can we specify an XPath expression to access element C (in the default namespace) ? The naive solution:
    /ns1:A/ns1:B/C
won't work. Many places (such as this) seem to indicate that there is just no way to do it. But is that really the case ?

Well, here is one that will do the job. The trick is simply to make use of the property that the local name of an element is equal to it's full name only if the element is in the default namespace.
    /ns1:A/ns1:B/*[local-name()=name()][name()='C']
or simply,
    /ns1:A/ns1:B/*[name()='C']
Why XPath doesn't have something simpler is beyond me.

Friday, August 05, 2005

 

Beanlib 2.4.1

Bealib 2.4.1 is now available for download from sourceforge. This is an enhancement release supporting customization of the Hibernate Bean Transformation process via the CustomHibernateBeanTransformable interface.

You can now selectively override the default transformation behavior by plugging in your own implementation of this interface to the HibernateBeanReplicator via the initCustomTransformer method.

A sample usage to handle the JDK1.5 enum can be found in the JUnit test here.

This page is powered by Blogger. Isn't yours?