Spring Hibernate JPA – Upload/Download File/Image to PostgreSQL with @Lob Example

In the tutorial, we guide how to upload/download file to PostGreSQL using Spring Hibernate JPA with @Lob annotation.

Technologies

– Java 1.8
– Maven 3.6.1
– Spring Tool Suite – Version 3.9.4.RELEASE
– PostgreSQL 9.6
– Spring Boot – 2.0.2.RELEASE

Goal

– We create a SpringBoot project as below structure:

-> Run & Check results:

SpringJPA-Upload-Download-File-Image-to-PostGreSQL-tables

Practice

Step to do
– Create SpringBoot project
– Create Data Model
– Create JPA Repository
– Implement Client to Download/Upload files
– Configure JPA connection

Create SpringBoot project

Using SpringToolSuite to create a SpringBoot project with dependencies:


	org.springframework.boot
	spring-boot-starter-data-jpa



	org.postgresql
	postgresql
	runtime

Create Data Model
package com.javasampleapproach.springjpa.savefile2postgresql.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Lob;
import javax.persistence.Table;
 
@Entity
@Table(name="file_model")
public class FileModel {
	@Id
    @Column(name = "id")
    private Long id;
	
    @Column(name = "name")
	private String name;
    
    @Column(name = "type")
	private String type;
	
	@Lob
    @Column(name="pic")
    private byte[] pic;
	
	public FileModel(){}
	
	public FileModel(long id, String name, String type, byte[] pic){
		this.id = id;
		this.name = name;
		this.type = type;
		this.pic = pic;
	}
	
	public Long getId(){
		return this.id;
	}
	
	public void setId(Long id){
		this.id = id;
	}
	
	public String getName(){
		return this.name;
	}
	
	public void setName(String name){
		this.name = name;
	}
	
	public String getType(){
		return this.type;
	}
	
	public void setType(String type){
		this.type = type;
	}
	
	public byte[] getPic(){
		return this.pic;
	}
	
	public void setPic(byte[] pic){
		this.pic = pic;
	}
}
Create JPA Repository
package com.javasampleapproach.springjpa.savefile2postgresql.jpa;

import org.springframework.data.jpa.repository.JpaRepository;

import com.javasampleapproach.springjpa.savefile2postgresql.model.FileModel;

public interface FilesRepository extends JpaRepository{
}
Implement Client to Download/Upload files
package com.javasampleapproach.springjpa.savefile2postgresql;

import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.Arrays;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.core.io.ClassPathResource;

import com.javasampleapproach.springjpa.savefile2postgresql.jpa.FilesRepository;
import com.javasampleapproach.springjpa.savefile2postgresql.model.FileModel;

@SpringBootApplication
public class SpringJpaSaveFiles2PostgreSqlApplication  implements CommandLineRunner{
	 
	@Autowired
	FilesRepository fileRepository;
	
	public static void main(String[] args) {
		SpringApplication.run(SpringJpaSaveFiles2PostgreSqlApplication.class, args);
	}
 
	@Override
	public void run(String... arg0) throws Exception {
		/*
		 *  images
		 */
		ClassPathResource jsaCoverImgFile = new ClassPathResource("files/jsa-cover.png");
		byte[] arrayData = new byte[(int) jsaCoverImgFile.contentLength()];
		jsaCoverImgFile.getInputStream().read(arrayData);
		FileModel coverModel = new FileModel(1, "JSA-Cover", "png", arrayData);
		
		ClassPathResource jsaVisionImgFile = new ClassPathResource("files/jsa-vision.png");
		arrayData = new byte[(int) jsaVisionImgFile.contentLength()];
		jsaVisionImgFile.getInputStream().read(arrayData);
		FileModel visionModel = new FileModel(2, "JSA-Vision", "png", arrayData);
		
		// file .txt
		ClassPathResource jsaAboutFile = new ClassPathResource("files/jsa-about.txt");
		arrayData = new byte[(int) jsaAboutFile.contentLength()];
		jsaAboutFile.getInputStream().read(arrayData);
		FileModel aboutModel = new FileModel(3, "JSA-About", "txt", arrayData);
					
		
		// store files to PostgreSQL via SpringJPA
		fileRepository.saveAll(Arrays.asList(coverModel, visionModel, aboutModel));
		
		// retrieve image from PostgreSQL via SpringJPA
		for(FileModel imageModel : fileRepository.findAll()){
			Files.write(Paths.get(  "download/" + imageModel.getName() + "." + imageModel.getType()), imageModel.getPic());
		}
	}
}
Configure JPA connection

– Open application.properties file, add connection setting:

spring.datasource.url=jdbc:postgresql://localhost/test
spring.datasource.username=postgres
spring.datasource.password=123
spring.jpa.generate-ddl=true
spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false

Why use setting spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false?

-> If you don’t have above setting, you will meet exception’s logs as below:

2018-05-28 12:00:53.698  INFO 7624 --- [           main] org.hibernate.dialect.Dialect            : HHH000400: Using dialect: org.hibernate.dialect.PostgreSQL95Dialect
2018-05-28 12:00:53.913  INFO 7624 --- [           main] o.h.e.j.e.i.LobCreatorBuilderImpl        : HHH000424: Disabling contextual LOB creation as createClob() method threw error : java.lang.reflect.InvocationTargetException

java.lang.reflect.InvocationTargetException: null
	at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_121]
	at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_121]

-> Above exception is not a real exception because Hibernate just tries to get some meta information from the database when loading.
So you can use spring.jpa.properties.hibernate.temp.use_jdbc_metadata_defaults=false to disable it.

Sourcecode

SpringJpaSaveFiles2PostgreSQL



By grokonez | May 28, 2018.


Related Posts


4 thoughts on “Spring Hibernate JPA – Upload/Download File/Image to PostgreSQL with @Lob Example”

  1. If you did not have generate-ddl set to true, what would the required DDL be to create the corresponding entity table? I guess what DDL was generated to create the table?

Got Something To Say:

Your email address will not be published. Required fields are marked *

*