Bitwise Operation In Hibernate 3

Hi all…
i encountered a small problem in doing bitwise operations with hibernate. Until now, HIbernate 2 HQL parser has supported bitwise operations. Hibernate 3 for some reason does not support it. So if you want to work around it, you have to create a custom SQLfunction and add it to the dialect, that will map the bitwise operator.

You have to create your own class, which will extend from StandardSQLFunction class and will implement SQLFunction interface. You have to override render() method from the interface mentioned before and provide your own implementation.

In my example I am showing how to use ampersand symbol (‘&’) for bitwise operation.

Important note:
Hibernate team people have changed SQLFunction interface when upgrading from version 3.0.2 to 3.0.3, so your custom implementation of bitwise operation in version 3.0.2 will not work in 3.0.3. So keep that in mind.

Update (13.Jan.2010):
According to one of the blog reader’s this example has successfully worked under Hibernate v.3.2.6!

Implementation:
I am using Sysbase dialect, so i will create a class that extends this dialect with my own implementation:

[java]
package com.project.test.dialect;

import org.hibernate.Hibernate;

public class SybaseDialect extends
org.hibernate.dialect.SybaseDialect{

public SybaseDialect() {
super();
registerFunction("bitwise_and",
new BitwiseAndFunction("bitwise_and",
Hibernate.INTEGER));
}

}
[/java]

What it means basically that i am registering a function by the name of bitwise_and the return type will be of type Integer.

Now, my custom class for SQLFunction like this:

[java]
package com.project.test.dialect;

import java.util.List;

import org.hibernate.QueryException;
import org.hibernate.dialect.function.SQLFunction;
import org.hibernate.dialect.function.StandardSQLFunction;
import org.hibernate.engine.SessionFactoryImplementor;
import org.hibernate.type.Type;

public class BitwiseAndFunction
extends StandardSQLFunction
implements SQLFunction {

public BitwiseAndFunction(String name) {
super(name);
}

public BitwiseAndFunction(String name, Type type) {
super(name, type);
}

public String render(List args,
SessionFactoryImplementor factory)
throws QueryException {
if (args.size() != 2) {
throw new IllegalArgumentException(
"the function must be passed 2 arguments");
}
StringBuffer buffer = new
StringBuffer(args.get(0).toString());
buffer.append(" & ").append(args.get(1));
return buffer.toString();
}
}
[/java]

The method render() accepts two arguments, if less – exception will be thrown. Once arguments are passed to the method, it will return a String that will look something like this (assuming that the passed arguments were one (1) and two (2)):

1 & 2

In my project, I am using named queries in my hbm.xml files, so below you can see a part of my hbm.xml file where I use my bitwise function:

[xml]
<query name="UserPermissionsForEnttiy">
select object(ep) from EntityPermission ep where ep.userid =
:userid and ep.entityid = :entityid and ep.classname =
:classname and bitwise_and(ep.permission,:requiredpermission) > 0
</query>
[/xml]

Note the two arguments that i am passing to the bitwise_and function.

Also not forget to update your persistence XML with your custom dialect class, this is how my persistence.xml looks like:

[xml]
<persistence>
<persistence-unit name="com.project.test.users">
<jta-data-source>java:/DefaultDS</jta-data-source>
<properties>
<property name="hibernate.dialect"
value="com.project.test.dialect.SybaseDialect"/>
<property name="hibernate.hbm2ddl.auto"
value="update"/>
<property name="hibernate.show_sql"
value="true"/>
.
.
.
</properties>
</persistence-unit>
</persistence>
[/xml]

Please note the hibernate.dialect property. As a value i gave the canonical name of my custom SysbaseDialect class.

Once you finished implementing your custom dialect classes, you can JAR them and put into the lib directory of your JBoss instance where the rest of your Hibernate libraries are.

Do not forget to restart your JBoss – it needs to load your newly added JAR, for you to be able to use it ;)

 

Comments are closed.