Spring-data-jpa storing blob

Autowire your repository interface and call the save method passing your entity object.

I have a similar setup which works pretty well:

@Autowired
Repository repository;

repository.save(entity);

@Entity
@Table(name = "something")
public class Message {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Lob
    @Column
    private byte[] data;

TL; DR

You can see sample project on my github. The project shows how you stream data to/from database.

Problem

All advices about mapping the @Lob as byte[] defeats (IMO) the main advantage of blobs - streaming. With byte[] everything gets loaded in memory. May be ok but if you go with LargeObject you likely want to stream.

Solution

Mapping

@Entity
public class MyEntity {

    @Lob
    private Blob data;

    ...

}

Configuration

Expose hibernate SessionFactory and CurrentSession so you can get hold of the LobCreator. In application.properties:

spring.jpa.properties.hibernate.current_session_context_class=org.springframework.orm.hibernate5.SpringSessionContext

Expose session factory as bean:

@Bean // Need to expose SessionFactory to be able to work with BLOBs
public SessionFactory sessionFactory(HibernateEntityManagerFactory hemf) {
    return hemf.getSessionFactory();
}

Create blob

@Service
public class LobHelper {

    private final SessionFactory sessionFactory;

    @Autowired
    public LobHelper(SessionFactory sessionFactory) {
        this.sessionFactory = sessionFactory;
    }

    public Blob createBlob(InputStream content, long size) {
        return sessionFactory.getCurrentSession().getLobHelper().createBlob(content, size);
    }

    public Clob createClob(InputStream content, long size, Charset charset) {
        return sessionFactory.getCurrentSession().getLobHelper().createClob(new InputStreamReader(content, charset), size);
    }
}

Also - as pointed out in comments - as long as you work with the @Blob including the stream you get you need to be within transaction. Just mark the working part @Transactional.


Spring Data does not handle BLOBs but Spring Content does. Specifically, Spring Content JPA stores content as BLOBs in the database and associates that content with an Entity through annotations.

pom.xml

   <!-- Java API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-jpa-boot-starter</artifactId>
      <version>0.0.11</version>
   </dependency>
   <!-- REST API -->
   <dependency>
      <groupId>com.github.paulcwarren</groupId>
      <artifactId>spring-content-rest-boot-starter</artifactId>
      <version>0.0.11</version>
   </dependency>

Entity.java

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

   @ContentId
   private String contentId;

   @ContentLength
   private long contentLength = 0L;

   // if you have rest endpoints
   @MimeType
   private String mimeType = "text/plain";

DataContentStore.java

@StoreRestResource(path="data")
public interface DataContentStore extends ContentStore<Data, String> {
}

The advantage of this approach over the accepted answer is that the Developer doesn't need to worry about any of the boilerplate code (the "service" in the accepted answer). The BLOB is also exposed as Spring Resource giving a natural programming interface. Or can be automatically exported via a REST interface. But none of this requires any coding, on behalf of the Developer, besides java config and the store interface.