Mapping a boolean with hibernate

There is a concept called a soft delete. While working with different persistence framework, sometimes you may not want to completely delete an entity from the database. I was working with hibernate and I had an entity named “User”. I didn’t want to completely delete this ‘User’ entity, rather than I wanted to keep a simple Boolean flag “deleted”.

At the very beginning I was too frustrated handing Boolean flag with hibernate. I was getting type cast exception.  I searched a lot, but didn’t find much information out there. So I was suggested to use text ‘true’ or ‘false’ a flag. But where I can store a single bit, it’s a defiantly bad idea to store a text(varchar).  At last I have solved it. I think, this text would be worthy if you face the same problem.

Let me show you how I solved it. here is my entity class ..

@Entity
@Table(name = "USER")
public class User implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;
@Column(name = "username")
private String username;
@Column(name = "password")
private String password;
@Transient
private String passwordConfirmed;
@Column(name = "email")
private String email;
@Column(name = "first_name")
private String firstName;
@Column(name = "last_name")
private String lastName;
@Column(name = "active")
private boolean active;
@Column(name = "deleted")
private boolean deleted;

//getter and setters

So here is my ‘deleted’ flag.  Whenever I need to delete my user, I need to change the flag. But normally sql database has no Boolean type. So here we have to maintain a bit or something else, may be tiny integers.  So here we need some conversions. If we use bit in sql database, and Boolean in our entity, we’ll need two conversions, bit to Boolean and Boolean to bit.

Doing this type of conversions all the time by hand maybe bad idea and I really didn’t want to do.

So I have to find out a better way.

Here’s the thing. Hibernate supports user type. We can create our own user type. So I have written my own user type. Here it is.

/****************
* @author: Bazlur Rahman Rokon
* @email: anm_brr@live.com
* @Dated: Jun 20, 2012
**************/

package org.codexplo.itax.util;

import java.io.Serializable;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;

import org.hibernate.HibernateException;
import org.hibernate.usertype.UserType;

public class MyBooleanType implements UserType {

private static final int[] SQL_TYPES = { Types.BIT };

@Override
public Object assemble(Serializable cached, Object owner)
throws HibernateException {
return cached;
}

@Override
public Object deepCopy(Object value) throws HibernateException {
return value;
}

@Override
public Serializable disassemble(Object value) throws HibernateException {
return (Serializable) value;
}

@Override
public boolean equals(Object x, Object y) throws HibernateException {
if (x == y) {
return true;
} else if (x == null || y == null) {
return false;
} else {
return x.equals(y);
}
}

@Override
public int hashCode(Object x) throws HibernateException {
assert (x != null);
return x.hashCode();
}

@Override
public boolean isMutable() {
return false;
}

@Override
public Object nullSafeGet(ResultSet resultSet, String[] names, Object owner)
throws HibernateException, SQLException {

return resultSet.getByte(names[0]) != 0;
}

@Override
public void nullSafeSet(PreparedStatement st, Object value, int index)
throws HibernateException, SQLException {
st.setByte(index, Boolean.TRUE.equals(value) ? (byte) 1 : (byte) 0);
}

@Override
public Object replace(Object orginal, Object arg1, Object arg2)
throws HibernateException {
return orginal;
}

@Override
public Class returnedClass() {
return Boolean.class;
}

@Override
public int[] sqlTypes() {
return SQL_TYPES;
}
}

Now life is simple, we just need to add an annotation in our entity.

This time, deleted field will look like-

@Type(type = "org.codexplo.itax.util.MyBooleanType")
@Column(name = "deleted")
private boolean deleted;

Now everything is simple, nothing to worry about conversion, you’ll never get type cast exception.

And whenever you need to delete your object, just get the object from database using hibernate, you may use dao layer. Then just change flag, deleted true, and the update it.

to know more about user type in hibernate, you may follow this link: http://docs.jboss.org/hibernate/orm/3.6/reference/en-US/html/types.html

Advertisements

2 Comments

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s