Google

Nov 14, 2013

Hibernate custom data type : Blob type example

There are times you want to define a custom data type in Hibernate. Here is an example of using a custom ImageType defined as a Blob databse type to store images, excel files, etc.

Step 1: Define the custom Hibernate data type "ImageTpe" as shown below.


 
package com.myapp.common;

import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.Serializable;
import java.sql.Blob;
import java.sql.PreparedStatement;
import java.sql.ResultSet;
import java.sql.SQLException;
import java.sql.Types;
import java.util.Arrays;

import org.hibernate.HibernateException;
import org.hibernate.engine.spi.SessionImplementor;
import org.hibernate.usertype.UserType;

public class ImageType implements UserType
{
    
    @Override
    public int[] sqlTypes()
    {
        return new int[]
        {Types.BLOB
        };
    }
    
    @Override
    public Class<Blob> returnedClass()
    {
        return Blob.class;
    }
    
    @Override
    public Object nullSafeGet(ResultSet rs, String[] names, SessionImplementor session, Object owner)
            throws HibernateException, SQLException
    {
        return getBlobFromBinaryStream(rs, names[0]);
    }
    
    private byte[] getBlobFromBinaryStream(ResultSet rs, String aColName)
            throws SQLException
    {
        
        byte[] theBuff = new byte[2 * 1024];
        InputStream theInStream = rs.getBinaryStream(aColName);
        
        ByteArrayOutputStream theBaos = new ByteArrayOutputStream();
        int n = 0;
        try
        {
            if (theInStream != null)
            {
                while (-1 != (n = theInStream.read(theBuff)))
                {
                    theBaos.write(theBuff, 0, n);
                }
            }
            theBaos.flush();
        }
        catch (IOException e)
        {
            e.printStackTrace();
        }
        
        return theBaos.toByteArray();
    }
    
    @Override
    public void nullSafeSet(PreparedStatement stmt, Object aValue, int aIndex, SessionImplementor session)
            throws HibernateException, SQLException
    {
        stmt.setBytes(aIndex, (byte[]) aValue);
    }
    
    @Override
    public boolean equals(Object obj, Object other)
    {
        if ((obj == other) ||
                (obj != null && other != null && Arraothers.equals(
                        ((byte[]) obj),
                        ((byte[]) other))))
        {
            return true;
        }
        return false;
    }
    
    @Override
    public int hashCode(Object obj) throws HibernateException
    {
        return obj.hashCode();
    }
    
    @Override
    public boolean isMutable()
    {
        return false;
    }
    
    @Override
    public Object assemble(Serializable aSerializableObject, Object obj) throws HibernateException
    {
        return null;
    }
    
    @Override
    public Serializable disassemble(Object onj) throws HibernateException
    {
        return null;
    }
    
    @Override
    public Object replace(Object obj1, obj2, Object obj3) throws HibernateException
    {
        return null;
    }
    
    @Override
    public Object deepCopy(Object obj)
    {
        return obj;
    }   
}


Step 2: Use the custom data type as shown below in Hibernate entity.

 
package com.myapp.model.images;

import java.util.Date;

import javax.persistence.AttributeOverride;
import javax.persistence.AttributeOverrides;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.EnumType;
import javax.persistence.Enumerated;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;
import javax.persistence.Table;

import org.hibernate.annotations.SQLDelete;
import org.hibernate.annotations.Type;
import org.hibernate.annotations.Where;

@Entity
@Table(name = "images", schema = "dbo", catalog = "my_catalog")
@Where(clause = "inactiveFlag = 'N'")
@SQLDelete(sql = "UPDATE MyImages SET inactiveFlag = 'Y' WHERE MyImagesID = ? and timestamp = ?")

public class MyImages 
{
    
    private static final long serialVersionUID = 1L;
    
    public enum Status
    {
        PENDINDING_RELEASE, RELEASED;
    }
    
    private String name;
    private byte[] image = new byte[0];
    private Status status;
    private byte[] timestamp;

    
    public MyImages()
    {
    }
    
    @Column(name = "name", nullable = false, length = 100)
    public String getName()
    {
        return name;
    }
    
    public void setName(String name)
    {
        this.name = name;
    }
    
 //custom type
    @Type(type = "com.myapp.common.ImageType")
    @Column(name = "rules", nullable = false)
    public byte[] getImage()
    {
        return image;
    }
    
    public void setImage(byte[] image)
    {
        this.image = image;
    }
    
    @Enumerated(EnumType.STRING)
    @Column(name = "Status", nullable = false, length = 30)
    public Status getStatus()
    {
        return status;
    }
    
    public void setStatus(Status status)
    {
        this.status = status;
    }
    
    @Version    
    @Column(name = "Timestamp", insertable = false, updatable = false, unique = true, nullable = false)
    @Generated(GenerationTime.ALWAYS)
 public byte[] getTimestamp() {
  return timestamp;
 }


 public void setTimestamp(byte[] timestamp) {
  this.timestamp = timestamp;
 }   
}




Labels:

0 Comments:

Post a Comment

Subscribe to Post Comments [Atom]

<< Home