1. Overview

LOB or Large OBject refers to a variable length datatype for storing large objects.

The datatype has two variants:

  • CLOB – Character Large Object will store large text data
  • BLOBBinary Large Object is for storing binary data like image, audio, or video

In this tutorial, we’ll show how we can utilize Hibernate ORM for persisting large objects.

2. Setup

For example, we’ll use Hibernate 5 and H2 Database. Therefore we must declare them as dependencies in our pom.xml:

<dependency>
    <groupId>org.hibernate</groupId>
    <artifactId>hibernate-core</artifactId>
    <version>6.1.7.Final</version>
</dependency>
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>2.1.214</version>
</dependency>

The latest version of the dependencies is in Maven Central Repositories: hibernate-core and h2.

For a more in-depth look at configuring Hibernate please refer to one of our introductory articles.

3. LOB Data Model

Our model “User” has id, name, and photo as properties. We’ll store an image in the User‘s photo property, and we will map it to a BLOB:

@Entity
@Table(name="user")
public class User {

    @Id
    private String id;
    
    @Column(name = "name", columnDefinition="VARCHAR(128)")
    private String name;
    
    @Lob
    @Column(name = "photo", columnDefinition="BLOB")
    private byte[] photo;

    // ...
}

The @Lob annotation specifies that the database should store the property as Large Object. The columnDefinition in the @Column annotation defines the column type for the property.

Since we’re going to save byte array, we’re using BLOB.

4. Usage

4.1. Initiate Hibernate Session

session = HibernateSessionUtil
  .getSessionFactory("hibernate.properties")
  .openSession();

Using the helper class, we will build the Hibernate Session using the database information provided in hibernate.properties file.

4.2. Creating User Instance

Let’s assume the user uploads the photo as an image file:

User user = new User();
        
InputStream inputStream = this.getClass()
  .getClassLoader()
  .getResourceAsStream("profile.png");

if(inputStream == null) {
    fail("Unable to get resources");
}
user.setId("1");
user.setName("User");
user.setPhoto(IOUtils.toByteArray(inputStream));

We convert the image file into the byte array by using the help of Apache Commons IO library, and finally, we assign the byte array as part of the newly created User object.

4.3. Persisting Large Object

By storing the User using the Session, the Hibernate will convert the object into the database record:

session.persist(user);

Because of the @Lob annotation declared on the class User, Hibernate understands it should store the “photo” property as BLOB data type.

4.4. Data Validation

We’ll retrieve the data back from the database and using Hibernate to map it back to Java object to compare it with the inserted data.

Since we know the inserted Users id, we will use it to retrieve the data from the database:

User result = session.find(User.class, "1");

Let’s compare the query’s result with the input User‘s data:

assertNotNull(
  "Query result is null", 
  result);
 
assertEquals(
  "User's name is invalid", 
  user.getName(), result.getName() );
 
assertTrue(
  "User's photo is corrupted", 
  Arrays.equals(user.getPhoto(), result.getPhoto()) );

Hibernate will map the data in the database to the Java object using the same mapping information on the annotations.

Therefore the retrieved User object will have the same information as the inserted data.

5. Conclusion

LOB is datatype for storing large object data. There’re two varieties of LOB which is called BLOB and CLOB. BLOB is for storing binary data, while CLOB is for storing text data.

Using Hibernate, we have demonstrated how it’s quite easy to map the data to and from Java objects, as long as we’re defining the correct data model and the appropriate table structure in the database.

As always the code for this article is available over on GitHub.