(注:このブログはもう更新していません)この日記は私的なものであり所属会社の見解とは無関係です。 GitHub: takahashikzn

[クラウド帳票エンジンDocurain]

@ManyToManyと@JoinTableを使ってuni-directionalにFetch Joinする

『店舗』と『商品』の間にN:Nの関係があったとします。
スキーマは次のような感じ。

-- 店舗
create table Shop (
    id bigint primary key,

    ...
);

-- 商品
create table Product (
    id bigint primary key,

    ...
);

-- 店舗がどの商品を扱うかの関連を表す (Associative Entity)
create table HandleProduct (
    shop_id bigint foreign key references Shop(id),
    product_id bigint foreign key references Product(id)
);

NGな例

こう書くと動きません。

@Entity
public class Shop {

    @Id
    private long id;

    @JoinTable(name = "HandleProduct", 
        joinColumns = @JoinColumn(name = "shop_id", referencedColumnName = "id"), 
        inverseJoinColumns = @JoinColumn(name = "product_id", referencedColumnName = "id"))
    private Set<Product> handleProducts;

    ...
}


@Entity
public class Product {
    @Id
    private long id;

    ...
}


"The parameter name [id] in the query's selection criteria does not match any parameter name defined in the query."

というエラーが出ます。

OKな例

こうすると動きます。

@Entity
public class Shop {

    @Id
    private long id;

    // referencedColumnNameを削除
    @JoinTable(name = "HandleProduct", 
        joinColumns = @JoinColumn(name = "shop_id"), 
        inverseJoinColumns = @JoinColumn(name = "product_id"))
    private Set<Product> handleProducts;

    ...
}


@Entity
public class Product {
    @Id
    private long id;

    ...
}


どうやら、referencedColumnNameで指定する文字列のケース依存がなんとかかんとか
だそうです。ちゃんと調べてないけど (-_-)