6

ORM ソリューションとして Hibernate + JPA を使用しています。

単体テストには HSQL を使用し、実際のデータベースには PostgreSQL を使用しています。

Postgres のネイティブUUIDタイプを Hibernate で使用できるようにしたいと考えています。ユニット テストでは、HSQL の String 表現で UUID を使用します (HSQL には UUID タイプがないため)。

Postgres と HSQL 単体テスト用に異なる構成の永続性 XML を使用しています。

Hibernate にカスタム UserType を「認識」させる方法は次のとおりです。

@Id
@Column(name="UUID", length=36)
@org.hibernate.annotations.Type(type="com.xxx.UUIDStringType")
public UUID getUUID() {
    return uuid;
}


public void setUUID(UUID uuid) {
    this.uuid = uuid;
}

そしてそれはうまくいきます。しかし、私が必要としているのは、XML の注釈の「com.xxx.UUIDStringType」部分を交換する機能、または再コンパイルせずに変更できるプロパティ ファイルから交換する機能です。

何か案は?

4

4 に答える 4

11

こんにちは、Hibernate 4 での解決策を探している人のために (Dialect#addTypeOverride メソッドが利用できなくなったため)、この Steve Ebersole のコメントの基礎となるものを見つけました

次のようなカスタム ユーザー タイプを作成する必要があります。

public class UUIDStringCustomType extends AbstractSingleColumnStandardBasicType {

    public UUIDStringCustomType() {
        super(VarcharTypeDescriptor.INSTANCE, UUIDTypeDescriptor.INSTANCE);
    }

    @Override
    public String getName() {
        return "pg-uuid";
    }

}

それを HSQLDB 方言にバインドするには、次のように Dialect#contributeTypes メソッドをオーバーライドするカスタム方言を作成する必要があります。

public class CustomHsqlDialect extends HSQLDialect {


    @Override
    public void contributeTypes(TypeContributions typeContributions, ServiceRegistry serviceRegistry) {
        super.contributeTypes(typeContributions,serviceRegistry);
        typeContributions.contributeType(new UUIDStringCustomType());
    }

}

次に、2 つのデータベースで @Type(type="pg-uuid") を使用できます。

それが誰かを助けることを願っています...

于 2015-07-21T06:56:45.453 に答える
6

この質問は非常に古く、長い間回答されてきましたが、最近、同じ状況に陥り、良い解決策を見つけました。手始めに、Hibernate には 3 つの異なる組み込み UUID タイプの実装があることを発見しました。

  1. binary-uuid: UUID をバイナリとして保存します
  2. uuid-char: UUID を文字シーケンスとして保存します
  3. pg-uuid: ネイティブの Postgres UUID タイプを使用します

これらのタイプはデフォルトで登録されており、特定のフィールドに@Type注釈を付けて指定できます。

@Column
@Type(type = "pg-uuid")
private UUID myUuidField;

には、デフォルトの型をオーバーライドするメカニズムありますDialect。したがって、最終的な展開が Postgres データベースと対話することであるが、単体テストで HSQL を使用する場合、次のpg-uuidようにカスタムの方言を記述することで、型をオーバーライドして文字データを読み書きすることができます。

public class CustomHSQLDialect extends HSQLDialect {

    public CustomHSQLDialect() {
        super();

        // overrides the default implementation of "pg-uuid" to replace it
        // with varchar-based storage.
        addTypeOverride(new UUIDCharType() {
            @Override
            public String getName() {
                return "pg-uuid";
            }
        });
    }
}

カスタム方言をプラグインするだけで、pg-uuidタイプは両方の環境で使用できます。

于 2014-07-02T04:18:30.153 に答える
4

注釈を指定せずに UUID タイプ間の問題を回避するために@Type(つまり、基本的に、postgres から mysql に、またはその逆に変更する場合は、すべての注釈を調整する必要があります...)その上でpackage-info.javahibernates@TypeDef注釈を使用しています。パッケージ。

アプリケーションの設定例を次に示します。エンティティが含まれている
と仮定します。module/src/main/java/app.package.domainそして、あなたのテストはに保存されていmodule/src/test/java/app.packageます。

パッケージに2 つ作成するだけpackage-info.javaです。domain

package-info ファイルが常に同じパッケージ内にあることを確認してください (テスト用と本番用)。以下の例を参照してください。

src/main/java
  app
    package
      domain
        package-info.java 

src/test/java
  app
    package
      domain
        package-info.java 

本番環境のコンテンツは次のpackage-info.javaようになります (Postgres):

@TypeDef(
  name = "pg-uuid",
  defaultForType = UUID.class,
  typeClass = PostgresUUIDType.class
)
package app.package.domain;

import org.hibernate.annotations.TypeDef;
import org.hibernate.type.PostgresUUIDType;

import java.util.UUID;

これは、「構成」をテストする方法です (H2):

@TypeDef(
  name = "uuid-char",
  defaultForType = UUID.class,
  typeClass = UUIDCharType.class
)
package app.package.domain;

import org.hibernate.annotations.TypeDef;
import org.hibernate.type.UUIDCharType;

import java.util.UUID;

それが役に立てば幸い

于 2016-11-27T12:12:08.117 に答える
2

おそらく、データベースの機能に応じて正しいことを行うために、ユーザーの種類にいくつかのスマートを構築できます。Hibernate 自体は、使用しているデータベースのタイプに応じて異なる動作をする「ネイティブ」ID ジェネレーターで同様のアプローチをとっています。このようなアプローチにより、実行時にマッピングを切り替える必要がなくなります。

たとえば、データベースごとに1 つの戦略クラスを作成できます。次に、ユーザー タイプ クラスで、初めて呼び出されたときに接続しているデータベースを検出し、そのデータベースの適切な戦略をインスタンス化してから、すべての呼び出しを戦略オブジェクトに委任します。

于 2009-06-17T14:11:54.443 に答える