Close

JPA - Persisting large data with @Lob annotation

[Updated: Aug 23, 2017, Created: Aug 23, 2017]

@Lob annotation is used to map fields/properties of large value to a corresponding database-supported large object type.

A Lob may be either a binary or character type.

The Lob annotation may be used in conjunction with the @Basic annotation. It can also be used with @ElementCollection, if annotated on the collection of basic type.

Example

In the following example, we are going to use @Lob on a string, byte[] and collection of strings.

@Entity
public class Report {
  @Id
  @GeneratedValue
  private long id;

  @Lob
  @Column(name = "CONTENT")
  private String reportContent;

  @Lob
  @ElementCollection
  @CollectionTable(name = "SUB_REPORTS", joinColumns = @JoinColumn(name = "SUB_RPT_FK"))
  @Column(name = "SUB_CONTENT")
  private List<String> subReportContents;

  @Lob
  @Column(name = "IMAGE")
  private byte[] reportImage;
    .............
}

Main class showing table mappings

public class ExampleMain {

  public static void main(String[] args) {
      EntityManagerFactory emf =
              Persistence.createEntityManagerFactory("example-unit");
      try {
          EntityManager em = emf.createEntityManager();
          nativeQuery(em, "SHOW TABLES");
          nativeQuery(em, "SHOW COLUMNS from REPORT");
          nativeQuery(em, "SHOW COLUMNS from SUB_REPORTS");
      } finally {
          emf.close();
      }
  }

  public static void nativeQuery(EntityManager em, String s) {
      System.out.printf("'%s'%n", s);
      Query query = em.createNativeQuery(s);
      List list = query.getResultList();
      for (Object o : list) {
          if (o instanceof Object[]) {
              System.out.println(Arrays.toString((Object[]) o));
          } else {
              System.out.println(o);
          }
      }
  }
}

Output

'SHOW TABLES'
[REPORT, PUBLIC]
[SUB_REPORTS, PUBLIC]
'SHOW COLUMNS from REPORT'
[ID, BIGINT(19), NO, PRI, NULL]
[CONTENT, CLOB(2147483647), YES, , NULL]
[IMAGE, BLOB(2147483647), YES, , NULL]
'SHOW COLUMNS from SUB_REPORTS'
[SUB_RPT_FK, BIGINT(19), NO, , NULL]
[SUB_CONTENT, CLOB(2147483647), YES, , NULL]

As seen in above output, strings are mapped to database type CLOB and byte[] to BLOB.

Persisting and loading data

public class ExampleMain2 {
  public static void main(String[] args) throws Exception {
      EntityManagerFactory emf =
              Persistence.createEntityManagerFactory("example-unit");
      try {
          persistEntity(emf);
          runNativeQuery(emf);
          loadEntity(emf);
      } finally {
          emf.close();
      }
  }

  private static void persistEntity(EntityManagerFactory emf) throws Exception {
      EntityManager em = emf.createEntityManager();
      Report report = new Report();
      report.setReportContent("a very big report....");
      //some dummy image
      report.setReportImage(new byte[]{1, 2, 3, 2, 1, 3, 3, 1, 5, 6});
      report.setSubReportContents(Arrays.asList("sub report 1....", "sub report 2...."));

      System.out.println("-- Persisting entity --");
      System.out.println(report);

      em.getTransaction().begin();
      em.persist(report);
      em.getTransaction().commit();
      em.close();
  }

  private static void runNativeQuery(EntityManagerFactory emf) {
      System.out.println("-- Native query --");
      EntityManager em = emf.createEntityManager();
      ExampleMain.nativeQuery(em, "Select * from REPORT");
      ExampleMain.nativeQuery(em, "Select * from SUB_REPORTS");
  }

  private static void loadEntity(EntityManagerFactory emf) {
      System.out.println("-- Loading entity --");
      EntityManager em = emf.createEntityManager();
      List<Report> entityAList = em.createQuery("Select t from Report t").getResultList();
      entityAList.forEach(System.out::println);
      em.close();
  }
}

Output

-- Persisting entity --
Report{id=0, reportContent='a very big report....', subReportContents=[sub report 1...., sub report 2....], reportImage=[1, 2, 3, 2, 1, 3, 3, 1, 5, 6]}
-- Native query --
'Select * from REPORT'
[1, clob1: 'a very big report....', blob0: X'01020302010303010506']
'Select * from SUB_REPORTS'
[1, clob2: 'sub report 1....']
[1, clob3: 'sub report 2....']
-- Loading entity --
Report{id=1, reportContent='a very big report....', subReportContents=[sub report 1...., sub report 2....], reportImage=[1, 2, 3, 2, 1, 3, 3, 1, 5, 6]}

Example Project

Dependencies and Technologies Used:

  • h2 1.4.196: H2 Database Engine.
  • hibernate-core 5.2.10.Final: The core O/RM functionality as provided by Hibernate.
    Implements javax.persistence:javax.persistence-api version 2.1
  • JDK 1.8
  • Maven 3.3.9

@Lob example Select All Download
  • jpa-lob-annotation
    • src
      • main
        • java
          • com
            • logicbig
              • example
                • Report.java
          • resources
            • META-INF

    See Also