大对象不能在自动提交模式下使用 [英] Large Objects may not be used in auto-commit mode
问题描述
我有一个 Spring 应用程序,它在 PostgreSQL 数据库上使用 Hibernate.我正在尝试将文件存储在数据库表中.它似乎将行与文件一起存储(我只是在 EntityManager 上使用持久方法),但是当从数据库加载对象时,我得到以下异常:
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.
为了加载数据,我使用了 MultipartFile 瞬态属性,并在其设置器中设置了我想要保留的信息(字节 []、文件名、大小).我坚持的实体看起来像这样(我省略了其余的 getter/setter):
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();
}
此方法仅在结果包含带有文件的对象时失败.我试图在我的persistence.xml中设置
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" />
但它并没有解决问题.
总的来说,应用程序运行良好,它只在事务完成时提交数据,如果出现故障,它会执行回滚,所以我不明白为什么会发生这种情况.
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.
有什么想法吗?
谢谢.
更新
查看 Shekhar 提供的链接,建议将调用包含在事务中,因此我在事务中设置了服务调用并且它可以工作(我添加了 @Transactional 注释).
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?
谢谢.
推荐答案
一个大对象可以存储在多个记录中,这就是您必须使用事务的原因.所有记录都正确或根本没有.
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/大对象.html
这篇关于大对象不能在自动提交模式下使用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!