1. ホーム
  2. java

[解決済み] JPAとHibernateのアソシエーションの一方向と双方向の違いは何ですか?

2022-04-23 13:33:29

質問

一方向関連付けと双方向関連付けの違いは何ですか?

dbに生成されたテーブルはすべて同じなので、私が見つけた唯一の違いは、双方向の関連付けの各側が他方を参照し、一方向の関連付けは参照しないことです。

これは単方向アソシエーションです

public class User {
    private int     id;
    private String  name;
    @ManyToOne
    @JoinColumn(
            name = "groupId")
    private Group   group;
}

public class Group {
    private int     id;
    private String  name;
}

双方向の関連付け

public class User {
    private int     id;
    private String  name;
    @ManyToOne
    @JoinColumn(
            name = "groupId")
    private Group   group;
}
public class Group {
    private int         id;
    private String      name;
    @OneToMany(mappedBy="group")
    private List<User>  users;
}

違いは、グループがユーザーのリファレンスを保持しているかどうかです。

ということは、これだけの違いなのかな? どちらがおすすめなのかな?

解決方法は?

主な違いは、双方向リレーションシップは双方向のナビゲーションアクセスを提供し、明示的なクエリなしで相手側にアクセスできることです。また、双方向にカスケード・オプションを適用することも可能です。

特に1対多や多対多のリレーションシップでは、ナビゲーションアクセスが常に良いとは限らないことに注意してください。例えば Group を含む数千の User s:

  • どのようにアクセスするのですか?これだけ多くの User を使用する場合、通常はフィルタリングやページ送りを行う必要があり、いずれにせよクエリを実行する必要があります。 コレクションフィルタリング 私にとってはハックにしか見えません)。開発者によっては、このような場合、メモリ上でフィルタリングを適用する傾向がありますが、これは明らかにパフォーマンス的によくありません。このような関係があると、この種の開発者がパフォーマンスへの影響を考えずに使ってしまう可能性があることに注意してください。

  • をどのように追加しますか? UserGroup ? 幸いなことに、Hibernate はリレーションシップを永続化する際に所有者側を見るので、リレーションシップに設定するのは User.group . しかし、メモリ上のオブジェクトの一貫性を保ちたい場合は、さらに UserGroup.users . しかし、これではHibernateが Group.users をデータベースから取得します。

からの提言には賛成できないわけです。 ベストプラクティス . ユースケース(両方向のナビゲーションアクセスが必要か)と起こりうるパフォーマンスへの影響を考慮し、双方向のリレーションシップを慎重に設計する必要があります。

こちらもご覧ください。