私は次を使用してアプリケーションを開発しています:
また、一部の文字列属性にPostgreSQLテキストデータ型を使用したいと思います。私の知る限り、JPAではこれはPostgreSQLでテキストを使用するための正しい注釈である必要があります。
@Entity
public class Product{
...
@Lob
private String description;
....
}
このようにエンティティに注釈を付けると、次のようなエラーが発生します。 http://www.shredzone.de/cilla/page/299/string-lobs-on-postgresql-with-hibernate-36 .html
要するに、休止状態とjdbcは、clob/text-typesに手をつないではいけないようです。
説明されているソリューションは機能しています:
@Entity
public class Product{
...
@Lob
@Type(type = "org.hibernate.type.TextType")
private String description;
...
}
しかし、これには重大な欠点があります。ソースコードはコンパイル時に休止状態にする必要があり、これは不要なはずです(そもそもJPAを使用する理由の1つです)。
別の方法は、次のように列注釈を使用することです。
@Entity
public class Product{
...
@Column(columnDefinition = "text")
private String description;
...
}
これはうまく機能しますが、テキストタイプ(およびテキストとも呼ばれます)を持つデータベースにこだわっています。また、将来別のデータベースが使用される場合、注釈は簡単に見落とされる可能性があります。したがって、データ型はStringで定義されているため、実行前に検出できないため、発生する可能性のあるエラーを見つけるのは困難です。
とても簡単な解決策はありますか、私にはわかりませんか? JPAをHibernateおよびPostgreSQLと組み合わせて使用しているのは私だけではないことを確信しています。ですから、このような質問をこれ以上見つけることができないと少し混乱しています。
質問を完了するために、persistence.xmlは次のようになります。
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0"
xmlns="http://Java.Sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://Java.Sun.com/xml/ns/persistence
http://Java.Sun.com/xml/ns/persistence/persistence_1_0.xsd">
<persistence-unit name="entityManager">
<provider>org.hibernate.ejb.HibernatePersistence</provider>
<class>com.app.model.Product</class>
<properties>
<property name="javax.persistence.jdbc.driver" value="org.postgresql.Driver" />
<property name="javax.persistence.jdbc.url"
value="jdbc:postgresql://localhost:5432/awesomedb" />
<property name="javax.persistence.jdbc.user" value="usr" />
<property name="javax.persistence.jdbc.password" value="pwd" />
<property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" />
<property name="hibernate.jdbc.use_streams_for_binary" value="false" />
<property name="hibernate.hbm2ddl.auto" value="create-drop" />
<property name="show_sql" value="true" />
</properties>
</persistence-unit>
</persistence>
UPDATE:
この問題はこの質問とほぼ同等です。選択された答えは、この質問で説明されている2番目の方法です。これは、実行時の休止状態依存性のために好きではありません: 任意の長さの文字列をPostgresqlに保存する
これは次のように関連しているようです: https://hibernate.atlassian.net/browse/JPA-48
text
型はSQL標準の一部ではないため、公式のJPAの方法はありません。
ただし、text
型はvarchar
と非常に似ていますが、長さの制限はありません。 @Column
のlength
プロパティを使用して、JPAの実装にヒントを与えることができます。
@Column(length=10485760)
private String description;
更新:10 MiBは、postgresqlのvarchar
の最大長のようです。 text
はalmost無制限で、 ドキュメント に従います:
いずれにせよ、保存できる最長の文字列は約1 GBです。
この注釈を追加する必要がありました。
@Column(columnDefinition="TEXT")
それ自体では機能しませんでした。データベースにテーブルを再作成する必要がありました。
DROP TABLE yourtable
または列タイプをtext
に変更しますALTER TABLE
ステートメント
プレーンなJPAを使用する場合は、次のように、使用されているCLOBタイプをダイアレクトに再マップできます。
public class PGSQLMapDialect extends PostgreSQL9Dialect {
@Override
public SqlTypeDescriptor remapSqlTypeDescriptor(SqlTypeDescriptor sqlTypeDescriptor) {
if (Types.CLOB == sqlTypeDescriptor.getSqlType()) {
return LongVarcharTypeDescriptor.INSTANCE;
}
return super.remapSqlTypeDescriptor(sqlTypeDescriptor);
}
}
そのため、列にOID=を使用し、ラージオブジェクト処理を介してテキストを格納/ロードするJDBCドライバーからのCLOBマッピングは使用しません。 VarcharTypeDescriptorクラスを介したPostgres JDBCドライバーのcreatetテキスト列。
単純なprivate String description;
。列タイプは、コードからデータベースを生成する場合にのみ問題になります。列タイプはvarchar
ではなくtext
として生成されるためです。
データベースに依存しない方法で、JPAベンダー固有のものなしでコーディングするのは素晴らしいことですが、これが不可能な場合もあります。現実には、複数のデータベースタイプとそのすべての詳細をサポートする必要がある場合、どこかでそれらの詳細を考慮する必要があります。 1つのオプションは、列タイプの定義にcolumnDefinition
を使用することです。もう1つの方法は、コードをそのままにして、データベースの列タイプを変更するだけです。私は2番目のものを好む。