Spring-data-jpa storing blob

后端 未结 6 1012
梦如初夏
梦如初夏 2021-02-04 14:17

What is \"best\" or canonical way to store entity with blob using spring-data-jpa?

@Entity
public class Entity {
  @Id
  private Long id;
  @Lob()
  private Blob         


        
6条回答
  •  天涯浪人
    2021-02-04 14:53

    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.

提交回复
热议问题