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 blob;
}
public interface Repository extends CrudRepository {
}
解决方案
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.