Member Menu
 
 Monthly JBoss newsletter:
 
Hibernate Books
CaveatEmptor

Blob(/Clob) as linked list

This is the implementation of storing a variable length blob/clob using a list of fixed length arrays.

For more details concerning the idea see:

http://forum.hibernate.org/viewtopic.php?t=936233

Hibernate Mapping file:

<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC
   "-//Hibernate/Hibernate Mapping DTD//EN"
   "http://hibernate.sourceforge.net/hibernate-mapping-2.0.dtd">

<hibernate-mapping>
    <class name="nl.chess.it.argus.core.db.blob.MyFile">
        <id name="dbId" type="java.lang.Long">
            <generator class="native" />
        </id>
        <property
            name="name"
            not-null="true"
            type="string"
         />
        <list
            cascade="all-delete-orphan"
            lazy="false"
            name="dataparts"
        >
            <key column="DBID_MYFILE" />
            <index column="NR" type="integer" />
            <element type="binary" >
            <!--
            PostgreSql
                <column name="dataaa" sql-type="bytea" length="10024"/>
            -->
            <!--
            MySql
                <column name="dataaa" sql-type="LONGBLOB" length="518576"/>
            -->
            <!--
            Oracle
                <column name="dataaa" sql-type="raw"/>
            -->
                <column name="dataaa" sql-type="LONGBLOB" length="518576"/>
            </element>
        </list>
    </class>
</hibernate-mapping>

Note: the java was generated with Hibernate Synchronizer in Eclipse, only the parts after the [CONSTRUCTOR MARKER END] are my work.


package nl.chess.it.argus.core.db.model;

import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

import nl.chess.it.argus.core.db.impl.LinkedListBlobPersister;
import nl.chess.it.argus.core.db.model.base.BaseLinkedListBlob;

/**
 * This class provides a generic blob as linked-list implementation that other classes can use.
 * 
 */
public class LinkedListBlob extends BaseLinkedListBlob implements LinkedListBlobPersister {
    private static int BUFFER_SIZE = 0;

/*[CONSTRUCTOR MARKER BEGIN]*/
    public LinkedListBlob () {}

    /**
     * Constructor for primary key
     */
    public LinkedListBlob (java.lang.Long _dbId) {
        super(_dbId);
    }

/*[CONSTRUCTOR MARKER END]*/
    
    
    /**
     * Set the bytes of this Object.
     * @param bytes the bytes to set, may not be null, but may be new byte[0];
     */
    public void setData(byte[] bytes) {
        int length = bytes.length;

        if ( length <= BUFFER_SIZE) {
            List partsList = new ArrayList();
            if ( length > 0 ) {
                partsList.add(bytes);
            }
            setDataparts(partsList);
            return;
        }
        
        int parts = length / BUFFER_SIZE;
        
        List partsList = new ArrayList(parts);
        
        for (int i = 0; i < parts; i++) {
            byte[] buffer = new byte[BUFFER_SIZE];
            System.arraycopy(bytes, i * BUFFER_SIZE, buffer, 0, BUFFER_SIZE );
            partsList.add(buffer);
        }

        int lastPartLength = length % BUFFER_SIZE;

        if ( lastPartLength != 0 ) {
            byte[] buffer = new byte[lastPartLength];
            System.arraycopy(bytes, parts * BUFFER_SIZE, buffer, 0, lastPartLength );
            partsList.add(buffer);
        }
        setDataparts(partsList);
        
    }
    

    /**
     * Gets the bytes that are stored by this object.
     * @return the data, not null but may be a new byte[0];
     */
    public byte[] getData() {

        int parts = getDataparts().size();

        if ( parts == 0) {
            return new byte[0];
        }

        if ( parts == 1) {
            return (byte[])getDataparts().get(0);
        }
       
        int lastPartLength = ((byte[])getDataparts().get(parts-1)).length;
        
        int dataLength = BUFFER_SIZE * (parts - 1) +  lastPartLength;
        
        byte[] bytes = new byte[dataLength];
        
        int count = 0;
        for (Iterator i = getDataparts().iterator(); i.hasNext();) {
            
            byte[] part = (byte[]) i.next();
            System.arraycopy(part, 0, bytes, count * BUFFER_SIZE, part.length );
            count ++;
        }
        
        return bytes;   
    }

    public void setBufferSize(int _bufferSize) {
        BUFFER_SIZE = _bufferSize;
    }
    
    public int getBufferSize() {
        return BUFFER_SIZE;
    }
}


  NEW COMMENT

Thanks 10 Jan 2005, 22:14 irfanmohammed
Can you please add the interface and the base class code in the wiki? 

Thanks a lot.
 
Thanks 16 Mar 2005, 20:21 jeeves21
Where is the interface and the rest of the classes? I couldnt find it 
on the wiki. How do I get hold of it?
 
© Copyright 2006, Red Hat Middleware, LLC. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc. [Privacy Policy]