Ich habe eine Spring-Anwendung, die Hibernate in einer PostgreSQL-Datenbank verwendet. Ich versuche, Dateien in einer Tabelle der Datenbank zu speichern. Es scheint es die Zeile mit der Datei speichert (ich verwende nur Methode auf EntityManager bestehen), aber wenn das Objekt aus der Datenbank, die ich die folgende Ausnahme erhalten geladen:Große Objekte dürfen nicht im automatischen Festschreibungsmodus verwendet werden
org.postgresql.util.PSQLException: Large Objects may not be used in auto-commit mode.
die Daten zu laden, ich bin mit Temporäres MultipartFile-Attribut und in seinem Setter setze ich die Information, die ich persistieren möchte (byte [], fileName, size). Das Unternehmen I aussieht wie dieser bin persistierende (ich habe den Rest von Getter/Setter weggelassen):
@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());
}
}
}
Ich kann sehen, dass, wenn es beibehalten wird ich die Daten in der Zeile haben, aber wenn ich rufe Diese Methode schlägt fehl:
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();
}
Diese Methode schlägt nur fehl, wenn das Ergebnis Objekte mit Dateien enthält. Ich habe versucht, in meine persistence.xml
<property name="hibernate.connection.autocommit" value="false" />
setzen, aber es löst das Problem nicht.
Im Allgemeinen funktioniert die Anwendung gut es Commit nur die Daten, wenn die Transaktion abgeschlossen ist und es führt einen Rollback, wenn etwas fehlschlägt, so verstehe ich nicht, warum das passiert.
Irgendeine Idee?
Danke.
UPDATE
bei der Verbindung von Shekhar gegeben Suche wird vorgeschlagen, den Anruf in einem transation aufzunehmen, also hat er den Service-Aufruf innerhalb einer Transaktion setze ein es funktioniert (ich habe hinzugefügt @Transactional Anmerkung).
Das Problem ist, dass ich keine Daten persistieren will, also verstehe ich nicht, warum es in einer Transaktion enthalten sein sollte. Macht es Sinn, einen Commit zu machen, wenn ich nur einige Daten aus der Datenbank geladen habe?
Danke.
Wenn Sie keine Daten persistieren möchten, warum haben Sie 'Dateien' gemappt? Sollte es nicht '@ Transient' sein? –
@matt b Ich möchte die Dateien aber nur in der Sicherungsoperation beibehalten, nicht in der gelesenen. Deshalb habe ich nicht verstanden, dass das Lesen in einer Transaktion sein sollte. – Javi
Sie verwenden @Transactional nicht nur, wenn Sie Objekte speichern möchten. In der Regel ist eine Transaktion erforderlich, um auf die Datenbank zugreifen zu können - egal ob Lesen oder Schreiben. – Volksman