1

私は Hibernate、Spring、JPA フレームワークの初心者です。とりあえず、Spring 3.1.1 - JPA with Hibernate 4 Implementation でシンプルなアーキテクチャを作ろうとしています。

とりあえず、データベースに依存しないようにするために、 TableGenerator でいくつかの ID を作成しました。

@Id
@Column(name = "AIR_ID", unique = true, nullable = false)
@TableGenerator(name="aircraftSeqStore", 
    table="T_S_APP_SEQ_STORE_AST", 
    pkColumnName="AST_SEQ_NAME",
    valueColumnName = "AST_SEQ_VALUE",
    pkColumnValue = "T_R_AIRCRAFT_AIR.AIR_ID", 
    allocationSize=1)
@GeneratedValue(strategy=GenerationType.TABLE, 
    generator="aircraftSeqStore")       
private Integer id;

私の調査の後、「dont-let-hibernate-steal-your-identity」の記事を読んだ後、ID の管理方法がよくわかりませんでした。

エンティティを変更して割り当てられた値に置き換える必要がありますか (JPA で行う方法は?)、一時オブジェクトの作成時に ID に直接影響を与える UUID を生成する必要がありますか?

多くのテーブルには、いくつかの簡単なデータ (ID、名前) があります。私は、一意であるがオブジェクトの作成時にも影響を受けない名前プロパティの hashcode および equals メソッドを管理できると考えました....(だから私は null である id を持つ同じ pb と思いますか?)。

詳細については、マルチ結合テーブル (この結合テーブルの 3 つの FK) を表すエンティティがあります。

それで、あなたは私に何をアドバイスしますか?パフォーマンスのために UUID を生成するのは悪くありませんか?


編集 :

このエンティティは実行可能ですか?

@Id
@Column(name = "AIR_ID", unique = true, nullable = false)
@TableGenerator(name="aircraftSeqStore", 
    table="T_S_APP_SEQ_STORE_AST", 
    pkColumnName="AST_SEQ_NAME",
    valueColumnName = "AST_SEQ_VALUE",
    pkColumnValue = "T_R_AIRCRAFT_AIR.AIR_ID", 
    allocationSize=1)
@GeneratedValue(strategy=GenerationType.TABLE, 
    generator="aircraftSeqStore")       
private Integer id;

@Column(name = "AIR_BUSINESS_ID", unique = true, nullable = false)
private String uuid = IdGenerator.createId();

public boolean equals(Object o) {
    if (this == o) return true;
    if (o == null || !(o instanceof Aircraft))
        return false;

    Aircraft other = (Aircraft)o;

    if (uuid == null) return false;
    return uuid .equals(other.getUuid ());
}

public int hashCode() {
    if (uuid  != null) {
        return uuid .hashCode();
    } else {
        return super.hashCode();
    }
}

ありがとうございました。

4

3 に答える 3

3

すべての質問と同様に、完全ではありますが、ほとんど役に立ちませんが、答えは次のとおりです。

より役立つバリアントは次のとおりです。

ほとんどの場合、GenerationType.Auto を使用し、equals と hashcode を実装していません。

結果は次のとおりです。

  • Hibernate は各データベース行がセッションごとに 1 つのインスタンスによって表されることを保証するため、エンティティ オブジェクトが同じセッション内に存在する限り、それらを比較しても問題ありません。

  • equals と hashcode は時間の経過とともに安定しているため、オブジェクトを HashSets に入れ、オブジェクトを変更しても、それらを再び取り出すことができます。

  • 異なるセッションのオブジェクトを操作したい場合は、おそらく Comparator を実装して、ID または ID + ハッシュコードまたはビジネス キーを明示的に比較する必要があります。何を使用するかを決定し、それを実装するために余分な労力を費やすと、実際には Hibernate の粒度に反することをしていることに気付くでしょう。

パフォーマンスについて: データベースとユースケースに応じて、UUID はかなり大きいためパフォーマンスが低下するか、クライアントで作成できるためパフォーマンスが向上し、データベースのラウンドトリップが節約されます。ほとんどの場合、アプリケーションの他のグリッチ (特に Hibernate を使用する場合) は、ID 生成の影響よりもはるかに大きくなります。

于 2012-08-10T10:32:04.147 に答える
0

私は最近、通常のパターンに代わる方法を探る質問をしました。この JPA の「キャッシュされた hashCode」パターンに落とし穴はありますか?

@Entityクラスで通常行うことの例を含めました-UUID構築時に を生成します。衝突の可能性UUIDは非常に小さいため、宇宙線について心配するのが最善です。UUID一部の人々は、パフォーマンスのペナルティがあると感じて s を好まない。と比較してパフォーマンスの変化は見られませんでしたが、衝突の可能性は十分に小さいため、問題になるIntegerと思います。Integer

@Id
private UUID id = UUID.randomUUID();

@Override
public boolean equals(Object obj) {
    if (this == obj)
        return true;
    if (!(obj instanceof MY_CLASS) || id == null)
        return false;
    MY_CLASS other = (MY_CLASS) obj;
    return id.equals(other.id);
}

@Override
public int hashCode() {
    Preconditions.checkNotNull(id, "id must be set before @Entity.hashCode can be called");
    return id.hashCode();
}

実際のデータ自体が一致するかどうかを確認したい場合があります。その場合は、次のようなメソッドを作成します。

public boolean hasSameProperties(Note other) {
    Preconditions.checkNotNull(other);
    if (this == other)
        return true;
    return Objects.equal(source, other.source)
            && Objects.equal(title, other.title)
            && Objects.equal(tags, other.tags)
            && Objects.equal(contents, other.contents);
}
于 2012-08-10T10:48:33.360 に答える
0

通常、私は使用します:

    @Id
@GeneratedValue(strategy=GenerationType.AUTO)     
    private Integer id

永続化プロバイダーに正しいものを選択させます。これがあなたを助けることを願っています

于 2012-08-10T10:21:41.027 に答える