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
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
Instead of using @Transactional
, all I did for this issue was to update this column in PostgreSQL DB from oid
type to bytea
type and added @Type
for the @Lob
field.
i.e.
ALTER TABLE person DROP COLUMN image;
ALTER TABLE person ADD COLUMN image bytea;
And changed
@Lob
private byte[] image;
To
@Lob
@Type(type = "org.hibernate.type.ImageType")
private byte[] image;
Use @Transactional
on your Repository Interface.
You should check if auto-commit is really set false with method getAutoCommit() on your Connection.
In my case
<property name="hibernate.connection.autocommit" value="false" />
did not work, because the type of my db connection required auto-commit to be true.
In my case the problem was in the JBoss Configuration. I was using an JTA-datasource and that caused the problem. With an XA-datasource it worked fine. See this post for more details.
If you can, create a intermediate Entity between MyClass and file property for instance. Something like:
@Entity
@Table(name="myobjects")
public class MyClass {
@OneToOne(cascade = ALL, fetch = LAZY)
private File file;
}
@Entity
@Table(name="file")
public class File {
@Lob
byte[] file;
}
You can't use @Lob and fetch type Lazy. It doesnt work. You must have a a intermediate class.
Unless you need to store files large than 1GB I suggest you use bytea as the datatype instead of large object.
bytea is basically what BLOB is in other databases (e.g. Oracle) and it's handling is a lot more compatible with JDBC.