2013-01-24 9 views
10
私たちは、この(グルーヴィーコード)のように見えますJPA注釈付きの型を使用している

PostgreSQL文字列をテキストタイプに移行するにはどうすればよいですか?

それは最初に私はJPAに非常に新しかったとSQLが最初に、その後、注釈付きクラスが一致して作っ書い書かれた
@Entity 
@EqualsAndHashCode 
class TextNote extends Serializable { 
    @Id Long id 
    String text 
} 

SQL。 PostgreSQLの上に読んで、以下は私が望んでいたテーブルだったようにそれが見えた:

CREATE TABLE textnote (
    id bigint NOT NULL, 
    text text 
); 

これは働いていた、と我々はこのように見えたテーブル持っていた:私は今、何をしたいか

id |   text 
-----+------------------------ 
837 | really long text here 

が正しいですJPAエンティティは次のように見て:

@Entity 
@EqualsAndHashCode 
class TextNote extends Serializable { 
    @Id Long id 
    @Lob String text 
} 

@Lob注釈にJPAプロバイダを追加することで(私の場合には、休止状態)の場合には私のために正しくDDLを生成することがありました我々はデータベースを交換したい。また、テキストフィールドが欲しいものを正確に文書化します。私はそれは本当に長いテキストを返します)文字列のgetTextを(使用してコードでそれを読んだときのように、新しいノートの罰金です

id |   text 
-----+------------------------ 
837 | 33427 

:今、ノートが作成されたとき、私はこのような何かを参照してください。正直なところ私はPostgreSQLがどのようにtextタイプを実装しているのか分かりませんし、理論的にもそうする必要はありません。しかし、本番データベースには、すでに@Lob注釈なしで古いコードを使って多くのメモが保存されています。既存のデータベースに新しいコードを実行するには、このような問題を生成します。既存の注意事項については

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 

、正しく@Lobtextタイプを使用するために、古いノートを移行するSQLでの方法はありますか?前もって感謝します。

答えて

12

Postgres large object docsに基づいて、各テキストチャンクをファイルに書き込んで個別にインポートする必要があるようです。あなたがSQLでやっているはずのものではありません。

私はJPAについて何も知らないけど、@LobはDDLやデータベースの切り替えと何が関係していますか?あなたは列のタイプを完全に変更しました。 Postgresのtextタイプで何が問題だったのですか?

これはコメントで失われていないので、ここでループを閉じる

本当の問題は@Lobは別の場所にデータを格納するネイティブのPostgresの「ラージオブジェクト」としてのPostgres text列が、Hibernate treats itを作成することでしたテーブル内のoidのみを残します(これは、カラムタイプごとにテキストとして保存されます)。これは通常あなたがテキストのために望むものではありません。

OPの解決策は、Hibernateに通常のテキストを保存させるために@Type(type="org.hibernate.type.StringClobType")を叩くことでした。

Postgresは通常、テキストを5桁の整数として格納しません。 :)

+0

から大きな助けを得、JPAプロバイダは、私が欲しいものではありませんカラム型のvarchar型、とテーブルを生成します。 '@Lob'はPostgreSQLの' text'型を生成します。これはまさに私が望むものです。データベースを切り替えるには、JPAプロバイダを使用してDDLを生成したいと考えています。それをするには '@ Lob'が必要です。理にかなっている? – Joe

+0

'@ Lob'が' text'を生成していますか?ドキュメントと投稿された出力の両方が 'oid'を生成すると思います。これはPostgresが大きなオブジェクトをどのように格納するのかです。本当に 'text'だったら、謎の数字ではなく_text_を見るだけです。 – Eevee

+0

私は肯定的です。ここには '@ Lob'アノテーションを付けて出力するテーブルがあります: [gist](https://gist.github.com/4630173) – Joe

7

JPAを使用してエンティティにアノテーションを付け、永続化するために休止状態にします。しかし、私は自分のエンティティにハイバネートのアノテーションを追加したくありません。したがって、エンティティとアノテーションを含むデータ・ジャーナルがあります。次に私の実装では、persistence.xmlを指定し、 'CustomTypes.hbm.xml'を追加します。自動的にスキャンされるか、またはpersistence.xml内のmapping-fileタグによって追加されます。

このマッピングには、私が基本指針からオーバーライドしたいタイプが含まれています。 この場合、materialized_clob型が使用されます。私はクエリツールでデータベースを参照すると、実際の内容を直接表示できるようにしたいので、私は欲しくない。 だから私は追加します。

<typedef name="materialized_clob" class="org.hibernate.type.TextType" /> 

を私のデータパッケージ内の特定の注釈を追加することなく、すべてのCLOBの場合、指定されたタイプの使用を強制するには。

DEBUGレベルでorg.hibernate.type.BasicTypeRegistryを記録することで、マッピングを確認できます。

これを理解するにはしばらく時間がかかりました。これが同じ問題に直面している人に役立つことを願っています。これはおそらくあなたの問題を解決するので、私はそれがここにそれを掲示する価値があるかもしれないと思った。

0

春を使用している場合は、LocalSessionFactoryBean子孫を作成して、Hibernate型のオーバーライドを挿入できます。例を参照してください:

public class CustomSessionFactoryBean extends LocalSessionFactoryBean { 

    @Override 
    protected SessionFactory buildSessionFactory(LocalSessionFactoryBuilder sfb) { 
     // To store @Lob annotated Strings in TEXT fields. 
     // By default for Postgres generated TEXT column, but stored OID of Postgres LOB object 
     sfb.registerTypeOverride(new TextType() { 
      @Override 
      public String getName() { 
       return StandardBasicTypes.MATERIALIZED_CLOB.getName(); 
      } 
     }); 
     sfb.registerTypeOverride(new NTextType() { 
      @Override 
      public String getName() { 
       return StandardBasicTypes.MATERIALIZED_NCLOB.getName(); 
      } 
     }); 

     super.buildSessionFactory(sfb); 
    } 
} 

あなたはHibernate固有のアノテーション@Typeを使用する必要はありません、私はその後半確信しているが、誰のために将来的には同じ問題を抱えてCustomSessionFactoryBean

1

@LobでStringプロパティに注釈を付け、使い。

また、OIDとしてではなく、列内のテキストの列に古いデータが直接存在するという同様の問題に直面しました。私は、アップグレードされたアプリケーションとそのデータを使用しようとしていたとき、私はあまりにも私がthis scriptを作成し、これを解決するには

Bad value for type long 

を得ていました。将来誰かを助けることができるかもしれない。

私はその注釈がなければ、このポストhere

関連する問題