Wie migriere ich PostgreSQL strings zu einem text geben?
Wir verwenden JPA-annotierten Typ, der so aussieht (groovy-code):
@Entity
@EqualsAndHashCode
class TextNote extends Serializable {
@Id Long id
String text
}
Wenn es zum ersten mal geschrieben, ich war sehr neu für JPA und schrieb die SQL der erste, dann aus den annotierten Klassen entsprechend SQL. Lesen Sie auf der PostgreSQL-es schien, dass die folgende war die Tabelle die ich wollte:
CREATE TABLE textnote (
id bigint NOT NULL,
text text
);
Funktionierte, und wir hatten Tische, die wie folgt aussah:
id | text
-----+------------------------
837 | really long text here
Was ich jetzt machen möchte, ist richtig in der JPA-Entity wie folgt Aussehen:
@Entity
@EqualsAndHashCode
class TextNote extends Serializable {
@Id Long id
@Lob String text
}
Indem die @Lob
Annotationen der JPA-provider (in meinem Fall, hibernate) generieren konnte die DDL richtig für mich im Falle wollen wir die swap-Datenbanken. Es ist auch dokumentiert, genau das, was ich will, das Textfeld zu werden. Wenn jetzt ein Hinweis erzeugt wird, sehe ich etwas wie dieses:
id | text
-----+------------------------
837 | 33427
Das ist gut für neue Noten, wie wenn ich es gelesen habe im code mit String getText() gibt den wirklich langen text. Ehrlich gesagt, ich weiß nicht, wie PostgreSQL implementiert die text
geben, noch muss ich in der Theorie. Aber unsere Produktions-Datenbank hat schon viele Notizen gespeichert, Alter code, ohne die @Lob
annotation. Mit dem neuen code auf einer vorhandenen Datenbank generiert werden Fragen wie diese:
org.springframework.dao.DataIntegrityViolationException: Bad value for type long : not a number this time; SQL [n/a]; nested exception is org.hibernate.exception.DataException: Bad value for type long : not a number this time
Für bestehende notes, gibt es eine Möglichkeit in SQL zu migrieren, die alten Noten zu verwenden @Lob
und text
korrekt eingeben? Vielen Dank im Voraus.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Basiert auf der PostgreSQL-large-object-docs es sieht aus wie Sie müssten, um zu schreiben, jeder text chunk einer Datei und importieren Sie Sie einzeln. Das ist nicht etwas, was Sie tun sollten, in SQL.
Ich weiß nicht, etwas über JPA, aber was tut
@Lob
zu tun haben, mit DDL oder Wechsel der Datenbanken? Sie habe sich völlig verändert die Art der Spalte; was war Los mit Postgres isttext
geben?Schließen der Schleife hier, damit das nicht verloren geht in den Kommentaren:
Das eigentliche problem war, dass
@Lob
schafft eine Postgrestext
Spalte, aber Hibernate behandelt als native Postgres "großes Objekt", die speichert die Daten an anderer Stelle und lässt nur eine oid in der Tabelle (die dann als text gespeichert, wie in der Spalte Typ). Dies ist in der Regel nicht, was Sie wollen für den text.OP ' s Lösung war ein Schlag auf
@Type(type="org.hibernate.type.StringClobType")
zu zwingen, Hibernate zum speichern normaler text.Postgres nicht normal speichern text als eine fünf-stellige Zahl. 🙂
@Lob
generiert die PostgreSQLtext
geben, das ist genau das, was ich will. Wenn ich es einschalten wollte, Datenbanken, ich möchte die Verwendung der JPA-provider zum generieren der DDL-Code für mich.@Lob
ist notwendig, um das zu tun. Sinn?@Lob
generierttext
? sowohl die Dokumentation und Ihre geposteten Ausgabe-ich denke, es würde zu generierenoid
—das ist, wie Postgres speichert große Objekte. wenn es wirklichtext
, Sie würde nur sehen, text, nicht ein Rätsel Nummer.@Lob
annotation: gisttext
Spalte, aber es ist unsinnig behandelt, als ein groß-Objekt-Spalte, der text sollte in der Tabelle angezeigt werden. (postgres absolut nicht speichern Sie normale text als zahlen.) Artikel links zu in dieser Frage ALSO, die mit einem ähnlichen problem.@Type(type="org.hibernate.type.StringClobType")
und der text ist gespeichert Menschen wieder lesbar. Ich denke, die ursprüngliche Frage basierte auf falschen Annahmen, PostgreSQL, vielen Dank für die Einstellung mich gerade! 🙂Verwende ich JPA zu kommentieren meine Entitäten und hibernate zu persistieren. Aber ich will nicht hinzufügen, hibernate-spezifische Annotationen zu meinem Entitäten. Deshalb habe ich eine jar-Daten mit den Entitäten + Anmerkungen. Dann in meiner Implementierung, die ich angeben persistence.xml und fügen Sie ein 'CustomTypes.hbm.xml'. Die auto-gescannt oder Hinzugefügt werden durch die mapping-Datei-tag in der persistence.xml.
Diese Zuordnung enthält die Typen, die ich überschreiben möchten von der basictyperegistry.
In diesem Fall ist der materialized_clob Typ verwendet wird. Das will ich nicht weil wenn ich meine Datenbank durchsuchen mit einer Abfrage-tool, ich möchte in der Lage sein, den tatsächlichen Inhalt direkt.
Also füge ich hinzu:
So erzwingen Sie die Verwendung des angegebenen Typs für alle clobs ohne die Notwendigkeit, spezifische Anmerkungen in meinem Daten-Paket.
Überprüfen Sie die Zuordnungen, indem Sie die Protokollierung org.hibernate.Typ.BasicTypeRegistry auf DEBUG-Stufe.
Es dauerte einige Zeit, um dies herauszufinden und ich hoffe, dies hilft jemand mit den gleichen Problemen. Weil das wird wahrscheinlich auch dein problem lösen, dachte ich, es könnte sich lohnen, posten Sie hier.
Ich bin sicher, seine zu spät, aber für jemand mit dem gleichen problem in Zukunft.
Ich auch vor ein ähnliches Problem hatte wo ich die alten Daten in den Spalten von text direkt in den Spalten nicht als OIDs. Und wenn ich versuche zu verwenden, dass die Daten mit den aktualisierten Anwendung wurde auch ich immer
Beheben, das ich erstellt dieses Skript. Möglicherweise kann es helfen, jemand in der Zukunft.
Bekam ich große Hilfe von diesem Beitrag hier
Wenn mit spring können Sie erstellen
LocalSessionFactoryBean
Nachkommen zu injizieren Hibernate-Typs außer Kraft setzen. Siehe Beispiel:Brauchen Sie nicht zu verwenden Hibernate-spezifische Annotationen
@Type
nur kommentieren String-Eigenschaft, mit@Lob
und verwendenCustomSessionFactoryBean