У меня есть приложение Spring, которое использует Hibernate в базе данных PostgreSQL. Я пытаюсь хранить файлы в таблице базы данных. Кажется, он хранит строку с файлом (я просто использовать метод сохраняются на EntityManager), но когда объект загружается из базы данных, я получаю следующее исключение:Большие объекты не могут использоваться в режиме автоматической фиксации
org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode.
Для загрузки данных я использую MultipartFile transient атрибут и его сеттер Я устанавливаю информацию, которую хочу сохранить (байт [], имя_файла, размер). Субъект я сохраняющийся выглядит как эта (я пропущен остальные добытчики/сеттера):
@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());
}
}
}
я могу видеть, что, когда она сохраняется у меня есть данные в строке, но когда я звоню этот метод не выполняется:
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
<property name="hibernate.connection.autocommit" value="false" />
но это не решит проблему.
В целом приложение хорошо работает, оно фиксирует данные только после завершения транзакции и выполняет откат, если что-то не удается, поэтому я не понимаю, почему это происходит.
Любая идея?
Спасибо.
UPDATE
Глядя на ссылку, заданной Шекхар предлагается включить вызов в транзакцию, поэтому я поставил вызов службы внутри транзакции об этом, это работает (я добавил @Transactional аннотация).
@Transactional
public List<myClass> find(String text) {
return myClassDAO.findByDescription(text);
}
проблема заключается в том, что я не хочу сохранять данные, поэтому я не понимаю, почему это должно быть включено внутри транзакции. Имеет ли смысл делать фиксацию, когда я загружал только некоторые данные из базы данных?
Спасибо.
если вы не хотите сохранять данные, почему у вас есть «файлы»? Разве это не должно быть «@ Transient»? –
@matt b Я хочу сохранить файлы, но только в операции сохранения, а не в прочитанной. Вот почему я не понял, что чтение должно быть в транзакции. – Javi
Вы не просто используете @Transactional, когда хотите сохранить объекты. Обычно требуется транзакция для доступа к базе данных - чтению или письму. – Volksman