Ich habe eine Anwendung, die Anmerkungen zu Ruhezustand 3.1 und JPA verwendet. Es enthält einige Objekte mit Byte [] -Attributen (1k - 200k groß). Es verwendet die Annotation JPA @Lob, und Hibernate 3.1 kann diese in allen wichtigen Datenbanken problemlos lesen - es scheint die Besonderheiten des JDBC-Blob-Anbieters zu verbergen (wie es sein sollte).
@Entity
public class ConfigAttribute {
@Lob
public byte[] getValueBuffer() {
return m_valueBuffer;
}
}
Wir mussten auf 3.5 aktualisieren, als wir feststellten, dass der Ruhezustand 3.5 diese Annotationskombination in postgresql (ohne Problemumgehung) unterbricht ( und nicht behebt ). Ich habe bisher keine eindeutige Lösung gefunden, aber ich habe festgestellt, dass beim Entfernen von @Lob der Postgresql-Typ bytea verwendet wird (was funktioniert, jedoch nur bei Postgres).
annotation postgres oracle works on
-------------------------------------------------------------
byte[] + @Lob oid blob oracle
byte[] bytea raw(255) postgresql
byte[] + @Type(PBA) oid blob oracle
byte[] + @Type(BT) bytea blob postgresql
once you use @Type, @Lob seems to not be relevant
note: oracle seems to have deprecated the "raw" type since 8i.
Ich suche nach einer Möglichkeit, eine einzelne kommentierte Klasse (mit einer Blob-Eigenschaft) zu haben, die über wichtige Datenbanken hinweg portierbar ist.
- Wie kann eine byte [] -Eigenschaft portabel kommentiert werden?
- Ist dies in einer neueren Version des Ruhezustands behoben?
Update: Nachdem ich diesen Blog gelesen habe, habe ich endlich herausgefunden, wie die ursprüngliche Problemumgehung in der JIRA-Ausgabe lautete: Anscheinend sollten Sie @Lob löschen und die Eigenschaft wie folgt kommentieren:
@Type(type="org.hibernate.type.PrimitiveByteArrayBlobType")
byte[] getValueBuffer() {...
Dies funktioniert jedoch nicht für mich - ich erhalte immer noch OIDs anstelle von Bytea; es funktionierte jedoch für den Autor der JIRA-Ausgabe, der anscheinend oid wollte.
Nach der Antwort von A. Garcia habe ich dann diese Combo ausprobiert, die tatsächlich auf postgresql funktioniert, aber nicht auf oracle.
@Type(type="org.hibernate.type.BinaryType")
byte[] getValueBuffer() {...
Was ich wirklich tun muss, ist zu steuern, welcher @ org.hibernate.annotations.Type die Kombination (@Lob + Byte [] wird zugeordnet) (auf postgresql).
Hier ist das Snippet von 3.5.5.Final von MaterializedBlobType (SQL-Typ Blob). Laut Steves Blog möchte postgresql, dass Sie Streams für bytea (fragen Sie mich nicht warum) und postgresqls benutzerdefinierten Blob-Typ für oids verwenden. Beachten Sie auch, dass die Verwendung von setBytes () unter JDBC auch für bytea gilt (aus früheren Erfahrungen). Dies erklärt also, warum Use-Streams keinen Einfluss darauf haben, dass beide "Bytea" annehmen.
public void set(PreparedStatement st, Object value, int index) {
byte[] internalValue = toInternalFormat( value );
if ( Environment.useStreamsForBinary() ) {
// use streams = true
st.setBinaryStream( index,
new ByteArrayInputStream( internalValue ), internalValue.length );
}
else {
// use streams = false
st.setBytes( index, internalValue );
}
}
Das führt zu:
ERROR: column "signature" is of type oid but expression is of type bytea
Update Die nächste logische Frage lautet: "Warum nicht einfach die Tabellendefinitionen manuell in bytea ändern" und das (@Lob + byte []) beibehalten? Dies funktioniert , BIS Sie versuchen, ein Null-Byte [] zu speichern. Was der postgreSQL-Treiber für einen Ausdruck vom Typ OID hält und der Spaltentyp bytea ist, liegt daran, dass der Ruhezustand (zu Recht) JDBC.setNull () anstelle von JDBC.setBytes (null) aufruft, was der PG-Treiber erwartet.
ERROR: column "signature" is of type bytea but expression is of type oid
Das Typsystem im Ruhezustand ist derzeit in Arbeit (gemäß 3.5.5 Verfallskommentar). Tatsächlich ist so viel vom 3.5.5-Code veraltet, dass es schwierig ist zu wissen, worauf zu achten ist, wenn PostgreSQLDialect unterklassifiziert wird.
AFAKT, Types.BLOB / 'oid' auf postgresql sollte einem benutzerdefinierten Typ zugeordnet werden, der JDBC-Zugriff im OID-Stil verwendet (dh PostgresqlBlobType-Objekt und NOT MaterializedBlobType). Ich habe Blobs noch nie erfolgreich mit postgresql verwendet, aber ich weiß, dass bytea einfach so funktioniert, wie ich es erwarten würde.
Ich sehe mir gerade die BatchUpdateException an - es ist möglich, dass der Treiber das Batching nicht unterstützt.
Tolles Zitat aus dem Jahr 2004: "Um meine Streifzüge zusammenzufassen, ich würde sagen, wir sollten warten, bis der JDBC-Treiber die LOBs ordnungsgemäß ausgeführt hat, bevor wir den Ruhezustand ändern."
Verweise:
- https://forum.hibernate.org/viewtopic.php?p=2393203
- https://forum.hibernate.org/viewtopic.php?p=2435174
- http://hibernate.atlassian.net/browse/HHH-4617
- http://postgresql.1045698.n5.nabble.com/Migration-to-Hibernate-3-5-final-td2175339.html
- https://jira.springframework.org/browse/SPR-2318
- https://forums.hibernate.org/viewtopic.php?p=2203382&sid=b526a17d9cf60a80f13d40cf8082aafd
- http://virgo47.wordpress.com/2008/06/13/jpa-postgresql-and-bytea-vs-oid-type/