581

違いは何ですか:

@Entity
public class Company {

    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
    @JoinColumn(name = "companyIdRef", referencedColumnName = "companyId")
    private List<Branch> branches;
    ...
}

@Entity
public class Company {

    @OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY, 
    mappedBy = "companyIdRef")
    private List<Branch> branches;
    ...
}
4

8 に答える 8

604

注釈@JoinColumnは、このエンティティが関係の所有者であることを示します(つまり、対応するテーブルには、参照されるテーブルへの外部キーを持つ列があります)。一方、属性mappedByは、この側のエンティティが関係の逆であることを示します。所有者は「他の」エンティティに存在します。これは、「mappedBy」で注釈を付けたクラスから他のテーブルにアクセスできることも意味します (完全な双方向の関係)。

特に、問題のコードの場合、正しい注釈は次のようになります。

@Entity
public class Company {
    @OneToMany(mappedBy = "company",
               orphanRemoval = true,
               fetch = FetchType.LAZY,
               cascade = CascadeType.ALL)
    private List<Branch> branches;
}

@Entity
public class Branch {
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "companyId")
    private Company company;
}
于 2012-08-13T16:20:09.490 に答える
248

@JoinColumn関係の両側で使用できます。質問はサイドでの使用についてでし@JoinColumn@OneToMany(まれなケース)。そして、ここでのポイントは、いくつかの追加のステートメントを生成する最適化されていないSQLクエリとともに、物理情報の複製(列名)にあります。UPDATE

ドキュメントによると:

JPA仕様では、多対1は(ほぼ)常に双方向関係の所有者側であるため、1対多の関連付けには次の注釈が付けられます。@OneToMany(mappedBy=...)

@Entity
public class Troop {
    @OneToMany(mappedBy="troop")
    public Set<Soldier> getSoldiers() {
    ...
}

@Entity
public class Soldier {
    @ManyToOne
    @JoinColumn(name="troop_fk")
    public Troop getTroop() {
    ...
} 

TroopSoldiertroopプロパティを介して双方向の1対多の関係があります。mappedByサイドで物理マッピングを定義する必要はありません(してはいけません) 。

1対多側を所有側として双方向の1対多をマップするには、mappedBy要素を削除し、多対1@JoinColumnをfalseに設定する必要がinsertableあります。updatableこのソリューションは最適化されておらず、いくつかの追加のUPDATEステートメントが生成されます。

@Entity
public class Troop {
    @OneToMany
    @JoinColumn(name="troop_fk") //we need to duplicate the physical information
    public Set<Soldier> getSoldiers() {
    ...
}

@Entity
public class Soldier {
    @ManyToOne
    @JoinColumn(name="troop_fk", insertable=false, updatable=false)
    public Troop getTroop() {
    ...
}
于 2012-08-13T17:10:55.900 に答える
34

アノテーションのmappedByは、理想的には、常に双方向関係の親側(Companyクラス)で使用する必要があります。この場合、子クラス(Branchクラス)のメンバー変数'company'を指すCompanyクラスで使用する必要があります。

注釈@JoinColumnは、エンティティの関連付けを結合するためのマップされた列を指定するために使用されます。この注釈は任意のクラス (親または子) で使用できますが、理想的には一方の側 (親クラスまたは子クラスではなく) でのみ使用する必要があります。両方で) ここでは、Branch クラスの外部キーを示す双方向関係の子側 (Branch クラス) で使用しました。

以下は実際の例です:

親クラス、会社

@Entity
public class Company {


    private int companyId;
    private String companyName;
    private List<Branch> branches;

    @Id
    @GeneratedValue
    @Column(name="COMPANY_ID")
    public int getCompanyId() {
        return companyId;
    }

    public void setCompanyId(int companyId) {
        this.companyId = companyId;
    }

    @Column(name="COMPANY_NAME")
    public String getCompanyName() {
        return companyName;
    }

    public void setCompanyName(String companyName) {
        this.companyName = companyName;
    }

    @OneToMany(fetch=FetchType.LAZY,cascade=CascadeType.ALL,mappedBy="company")
    public List<Branch> getBranches() {
        return branches;
    }

    public void setBranches(List<Branch> branches) {
        this.branches = branches;
    }


}

子クラス、ブランチ

@Entity
public class Branch {

    private int branchId;
    private String branchName;
    private Company company;

    @Id
    @GeneratedValue
    @Column(name="BRANCH_ID")
    public int getBranchId() {
        return branchId;
    }

    public void setBranchId(int branchId) {
        this.branchId = branchId;
    }

    @Column(name="BRANCH_NAME")
    public String getBranchName() {
        return branchName;
    }

    public void setBranchName(String branchName) {
        this.branchName = branchName;
    }

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="COMPANY_ID")
    public Company getCompany() {
        return company;
    }

    public void setCompany(Company company) {
        this.company = company;
    }


}
于 2014-11-05T10:01:40.090 に答える
20

この回答が示唆するように、必ずしも物理的な情報@JoinColumnの場所に関連している必要はありません。親テーブルに子テーブルを指すテーブル データがない場合でも結合できます。@JoinColumn@OneToMany

JPA で一方向の OneToMany 関係を定義する方法

単方向の OneToMany、逆多対一なし、結合テーブルなし

しかし、それはでしか利用できないようですJPA 2.x+。子クラスに完全な参照ではなく、親の ID だけを含めたい場合に便利です。

于 2015-09-11T15:12:43.720 に答える
5

簡単にしましょう。マッピングに関係なく、どちらの側でも@JoinColumn
を 使用できます。

これを3つのケースに分けてみましょう。
1) 支店から会社への一方向マッピング。
2) 会社から支店への双方向マッピング。
3) 会社から支社への一方向のマッピングのみ。

したがって、どのユースケースもこの 3 つのカテゴリに分類されます。@JoinColumnmappingByの使い方を説明します。
1) 支店から会社への一方向マッピング。ブランチ テーブルでJoinColumn
を 使用します。 2) 会社から支店への双方向マッピング。@Mykhaylo Adamovychの回答で説明されているように、CompanyテーブルでmappedByを 使用してください。 3) 会社から支社への一方向マッピング。Company テーブルで@JoinColumnを 使用するだけです。



@Entity
public class Company {

@OneToMany(cascade = CascadeType.ALL , fetch = FetchType.LAZY)
@JoinColumn(name="courseId")
private List<Branch> branches;
...
}

これは、ブランチ テーブルの外部キー「courseId」マッピングに基づいて、すべてのブランチのリストを取得することを意味します。注: この場合、ブランチから会社をフェッチすることはできません。会社からブランチへの一方向のマッピングのみが存在します。

于 2020-05-17T07:53:45.563 に答える