0

I want to save large objects to postgresql using hibernate jpa.

My code for entity class is given below:

@Entity
@Table(name = "catalog_image", schema = "public")
public class CatalogImage {

@Id
@GeneratedValue
private int imageId;

@Column(name = "image_name")
private String imageName;

@Lob
@Column(name = "image")
private Blob catlogImg;

@Column(name = "category")
private String category;

@Column(name = "image_size")
private long imgSize;

public int getImageId() {
    return imageId;
}

public void setImageId(int imageId) {
    this.imageId = imageId;
}

public String getImageName() {
    return imageName;
}

public void setImageName(String imageName) {
    this.imageName = imageName;
}

public Blob getCatlogImg() {
    return catlogImg;
}

public void setCatlogImg(Blob catlogImg) {
    this.catlogImg = catlogImg;
}

public String getCategory() {
    return category;
}

public void setCategory(String category) {
    this.category = category;
}

public long getImgSize() {
    return imgSize;
}

public void setImgSize(long imgSize) {
    this.imgSize = imgSize;
}


public CatalogImage() {
    super();
}

}

The code for saving the image is

@Override
@Transactional
public CatalogImage saveOrUpdateCatalogImage(String category, MultipartFile image) throws Exception {
    CatalogImage img = new CatalogImage();
    Blob blob=Hibernate.getLobCreator(sessionFactory.getCurrentSession()).createBlob(image.getInputStream(),image.getSize());
    img.setCatlogImg(blob);
    img.setCategory(category);
    img.setImageName(image.getOriginalFilename());
    img.setImgSize(image.getSize());
    this.sessionFactory.getCurrentSession().saveOrUpdate(img);
    return img;
}

But it is not getting saved. I am getting the error message as below:

org.hibernate.exception.GenericJDBCException: could not insert: [com.book.image.accountservice.model.CatalogImage]
at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:47) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:109) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2911) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3386) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:89) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:560) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:434) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:337) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1282) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.springframework.orm.hibernate4.SpringSessionSynchronization.beforeCommit(SpringSessionSynchronization.java:104) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.transaction.support.TransactionSynchronizationUtils.triggerBeforeCommit(TransactionSynchronizationUtils.java:95) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.triggerBeforeCommit(AbstractPlatformTransactionManager.java:932) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:744) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:730) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:483) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:290) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:655) ~[spring-aop-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at com.inapp.posbook.accountservice.dao.MasterDataDaoImpl$$EnhancerBySpringCGLIB$$3df5a42c.saveOrUpdateCatalogImage(<generated>) ~[classes/:na]
at com.inapp.posbook.accountservice.service.MasterDataServiceImpl.saveOrUpdateCatalogImage(MasterDataServiceImpl.java:315) ~[classes/:na]
at com.inapp.posbook.accountservice.controller.MasterDataController.uploadCatalogImage(MasterDataController.java:547) ~[classes/:na]
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_05]
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62) ~[na:1.8.0_05]
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) ~[na:1.8.0_05]
at java.lang.reflect.Method.invoke(Method.java:483) ~[na:1.8.0_05]
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:221) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136) ~[spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:114) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:827) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:738) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:85) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:963) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:897) ~[spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:970) [spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.servlet.FrameworkServlet.doPost(FrameworkServlet.java:872) [spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:648) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:846) [spring-webmvc-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at javax.servlet.http.HttpServlet.service(HttpServlet.java:729) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:230) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:52) [tomcat-embed-websocket-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.boot.web.filter.ApplicationContextHeaderFilter.doFilterInternal(ApplicationContextHeaderFilter.java:55) [spring-boot-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.boot.actuate.trace.WebRequestTraceFilter.doFilterInternal(WebRequestTraceFilter.java:105) [spring-boot-actuator-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.web.filter.RequestContextFilter.doFilterInternal(RequestContextFilter.java:99) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.web.filter.HttpPutFormContentFilter.doFilterInternal(HttpPutFormContentFilter.java:87) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.web.filter.HiddenHttpMethodFilter.doFilterInternal(HiddenHttpMethodFilter.java:77) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.web.filter.CharacterEncodingFilter.doFilterInternal(CharacterEncodingFilter.java:197) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.springframework.boot.actuate.autoconfigure.MetricsFilter.doFilterInternal(MetricsFilter.java:107) [spring-boot-actuator-1.4.0.RELEASE.jar:1.4.0.RELEASE]
at org.springframework.web.filter.OncePerRequestFilter.doFilter(OncePerRequestFilter.java:107) [spring-web-4.3.2.RELEASE.jar:4.3.2.RELEASE]
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:192) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:165) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:198) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:108) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:522) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:140) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:79) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:349) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.coyote.http11.Http11Processor.service(Http11Processor.java:1110) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.coyote.AbstractProtocol$ConnectionHandler.process(AbstractProtocol.java:785) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.tomcat.util.net.NioEndpoint$SocketProcessor.doRun(NioEndpoint.java:1425) [tomcat-embed-core-8.5.4.jar:8.5.4]
at org.apache.tomcat.util.net.SocketProcessorBase.run(SocketProcessorBase.java:49) [tomcat-embed-core-8.5.4.jar:8.5.4]
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_05]
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_05]
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61) [tomcat-embed-core-8.5.4.jar:8.5.4]
at java.lang.Thread.run(Thread.java:745) [na:1.8.0_05]
Caused by: org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode.
at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:304) ~[postgresql-9.4-1206-jdbc42.jar:9.4]
at org.postgresql.largeobject.LargeObjectManager.createLO(LargeObjectManager.java:291) ~[postgresql-9.4-1206-jdbc42.jar:9.4]
at org.postgresql.jdbc2.AbstractJdbc2Statement.createBlob(AbstractJdbc2Statement.java:3127) ~[postgresql-9.4-1206-jdbc42.jar:9.4]
at org.postgresql.jdbc2.AbstractJdbc2Statement.setBlob(AbstractJdbc2Statement.java:3180) ~[postgresql-9.4-1206-jdbc42.jar:9.4]
at org.hibernate.type.descriptor.sql.BlobTypeDescriptor$4$1.doBind(BlobTypeDescriptor.java:132) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.type.descriptor.sql.BasicBinder.bind(BasicBinder.java:74) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:257) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.type.AbstractStandardBasicType.nullSafeSet(AbstractStandardBasicType.java:252) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.type.AbstractSingleColumnStandardBasicType.nullSafeSet(AbstractSingleColumnStandardBasicType.java:39) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.dehydrate(AbstractEntityPersister.java:2598) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:2883) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
... 86 common frames omitted

Note: I have tried byte[], but getting the same error. I am using spring boot, hibernate and postgresql db.

2 Answers 2

2

Try this, convert MultipartFile image to byte[] and use bytea datatype in postgresql to store it:

@Entity
@Table(name = "catalog_image", schema = "public")
public class CatalogImage {

@Id
@GeneratedValue
private int imageId;

@Column(name = "image_name")
private String imageName;

@Lob
@Column(name = "image")
private byte[] catlogImg;

@Column(name = "category")
private String category;

@Column(name = "image_size")
private long imgSize;

public int getImageId() {
    return imageId;
}

public void setImageId(int imageId) {
    this.imageId = imageId;
}

public String getImageName() {
    return imageName;
}

public void setImageName(String imageName) {
    this.imageName = imageName;
}

public byte[] getCatlogImg() {
    return catlogImg;
}

public void setCatlogImg(byte[] catlogImg) {
    this.catlogImg = catlogImg;
}

public String getCategory() {
    return category;
}

public void setCategory(String category) {
    this.category = category;
}

public long getImgSize() {
    return imgSize;
}

public void setImgSize(long imgSize) {
    this.imgSize = imgSize;
}


public CatalogImage() {
    super();
}

} 

And code for processing image is:

@Override
@Transactional
public CatalogImage saveOrUpdateCatalogImage(String category, MultipartFile image) throws Exception {
    CatalogImage img = new CatalogImage();
    byte[] imageData = new byte[(int) image.length()];
    try {
    FileInputStream fileInputStream = new FileInputStream(image);
    fileInputStream.read(imageData);
    fileInputStream.close();
    } catch (Exception e) {
    e.printStackTrace();
    }
    img.setCatlogImg(imageData);
    img.setCategory(category);
    img.setImageName(image.getOriginalFilename());
    img.setImgSize(image.getSize());
    this.sessionFactory.getCurrentSession().saveOrUpdate(img);
    return img;
}
Sign up to request clarification or add additional context in comments.

2 Comments

Hi, Hope this works.... Thank you... I have removed @Lob from entity class.
In this case, you store all data in memory. I tried to do something like this but with a Blob object. It stores data in the DB, but when you get the Blob object from the DB, it loads all the data into memory (into the buffer of the Blob's InputStream). I don't understand what to do if the object is large (hello, OOM). I understand that storing large objects in the database isn't the best idea, but there's no other way.
0

Want to confirm something. Have you made these changes in your project?:

Required Jar:

<dependency>
    <groupId>commons-fileupload</groupId>
    <artifactId>commons-fileupload</artifactId>
    <version>1.3.1</version>
</dependency>

Context-xml configuration:

<beans:bean class="org.springframework.web.multipart.commons.CommonsMultipartResolver">
    <!-- setting maximum upload size -->
    <beans:property name="maxUploadSize" value="100000" />
</beans:bean>

3 Comments

yes, I have added dependency and given maximum size
actually the root cause is org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode". So try adding this property in your database configurations hibernate.hikari.autoCommit=false
I have tried that also. The above code works for me.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.