大对象不能用于自动提交模式 [英] Large Objects may not be used in auto-commit mode

查看:597
本文介绍了大对象不能用于自动提交模式的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个在PostgreSQL数据库上使用Hibernate的Spring应用程序。我试图将文件存储在数据库的表中。看起来它存储行与文件(我只是在EntityManager上使用persist方法),但是当从数据库加载对象时,我得到以下异常:

  org.postgresql.util.PSQLException:大对象不能用于自动提交模式。 

为了加载数据,我使用了MultipartFile transient属性,并在其setter中设置了我想要坚持的信息(字节[],文件名,大小)。
我坚持的实体看起来像这样(我已经省略了getters / setters的其余部分):

  @Entity 
@Table(name =myobjects)
public class MyClass {

@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE,generator =序列)
@SequenceGenerator(name =sequence,sequenceName =myobjects_pk_seq,allocationSize = 1)
@Column(name =id)
private Integer id;

@Lob
私有字符串描述;

@Temporal(TemporalType.TIMESTAMP)
私人日期creationDate;

@Transient
private MultipartFile multipartFile;

@Lob
@Basic(fetch = FetchType.LAZY,可选= true)
byte [] file;

字符串文件名;

String fileContentType;

整数fileSize;

public void setMultipartFile(MultipartFile multipartFile){
this.multipartFile = multipartFile;
尝试{
this.file = this.multipartFile.getBytes();
this.fileName = this.multipartFile.getOriginalFilename();
this.fileContentType = this.multipartFile.getContentType();
this.fileSize =((Long)this.multipartFile.getSize())。intValue();
} catch(IOException e){
logger.error(e.getStackTrace());
}
}
}

我可以看到,是持久的我有行中的数据,但是当我调用这个方法时,它失败了:

  public List< MyClass> findByDescription(String text){
Query query = getEntityManager()。createQuery(from MyClass WHERE UPPER(description)like:query ORDER BY creationDate DESC);
query.setParameter(query,%+ text.toUpperCase()+%);
返回query.getResultList();
}

只有当结果包含带有文件的对象时,此方法才会失败。我尝试在我的persistence.xml中设置

 < property name =hibernate.connection.autocommitvalue =假/> 

但它不能解决问题。



通常情况下,应用程序运行良好,只有在事务完成时才提交数据,并且在发生某种情况时会执行回滚,所以我不明白为什么会发生这种情况。



有什么想法?



谢谢。

>

查看Shekhar给出的链接,建议将该调用包含在转换中,因此我在事务内部设置了服务调用(它添加了@

  @Transactional 
public List< myClass> find(String text){
return myClassDAO.findByDescription(text);
}

问题是我不想保存任何数据,所以我不会不明白为什么它应该包含在交易中。
$ b

谢谢。

解决方案

大对象可以存储在多个记录中,这就是为什么您必须使用事务。所有记录都是正确的或根本没有。



https://www.postgresql.org/docs/current/static/largeobjects.html


I have a Spring application which uses Hibernate on a PostgreSQL database. I'm trying to store files in a table of the database. It seems it stores the row with the file (I just use persist method on EntityManager), but when the object is loaded from the database I get the following exception:

org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode.

To load the data I'm using a MultipartFile transient atribute and in its setter I'm setting the information I want to persist (byte[], fileName, size). The entity I'm persisting looks like this one (I've ommitted the rest of getters/setters):

@Entity
@Table(name="myobjects")
public class MyClass {

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="sequence")
    @SequenceGenerator(name="sequence", sequenceName="myobjects_pk_seq", allocationSize=1)
    @Column(name="id")
    private Integer id;

    @Lob
    private String description;

    @Temporal(TemporalType.TIMESTAMP)
    private Date creationDate;

    @Transient
    private MultipartFile multipartFile;

    @Lob
    @Basic(fetch=FetchType.LAZY, optional=true)
    byte[] file;

    String fileName;

    String fileContentType;

    Integer fileSize;

    public void setMultipartFile(MultipartFile multipartFile) {
        this.multipartFile = multipartFile;
        try {
            this.file = this.multipartFile.getBytes();
            this.fileName = this.multipartFile.getOriginalFilename();
            this.fileContentType = this.multipartFile.getContentType();
            this.fileSize = ((Long) this.multipartFile.getSize()).intValue();
        } catch (IOException e) {
            logger.error(e.getStackTrace());
        }
    }
}

I can see that when it is persisted I have the data in the row but when I call this method it fails:

public List<MyClass> findByDescription(String text) {
    Query query = getEntityManager().createQuery("from MyClass WHERE UPPER(description) like :query ORDER BY creationDate DESC");
    query.setParameter("query", "%" + text.toUpperCase() + "%");
    return query.getResultList();
}

This method only fails when the result has objects with files. I've tried to set in my persistence.xml

<property name="hibernate.connection.autocommit" value="false" />

but it doesn't solve the problem.

In general the application works well it only commit the data when the transaction is finished and it performs a rollback if something fails, so I don't understand why is this happening.

Any idea?

Thanks.

UPDATE

Looking at the link given by Shekhar it is suggested to include the call in a transation, so I've set the service call inside a transaction an it works (I've added @Transactional annotation).

@Transactional
public List<myClass> find(String text) {
    return myClassDAO.findByDescription(text);
}

the problem is that I don't want to persist any data so I don't understand why it should be include inside a transaction. Does it make any sense to make a commit when I've only loaded some data form the database?

Thanks.

解决方案

A large object can be stored in several records, that's why you have to use a transaction. All records are correct or nothing at all.

https://www.postgresql.org/docs/current/static/largeobjects.html

这篇关于大对象不能用于自动提交模式的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆