質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

ただいまの
回答率

90.36%

  • Java

    15108questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Spring

    787questions

    Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

  • Spring Boot

    664questions

    Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

  • Hibernate

    41questions

    HibernateとはJava言語のobject-relational mapping (ORM)ライブラリであり、Object/Relational Mappingよりはるか多くの方法でアプリケーションをPOJOで機能付けることができます。

【Spring Boot】【JPA】テーブル結合が上手くいかない

解決済

回答 2

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 7,856

shiva768

score 1

前提・実現したいこと

下記のようなjoinをjpaで実現したいです。

select p.parent_name, c.* from Parent p inner join Child c on p.parent_id= c.parent_id;

entity情報

一部実際の実装に近い形に修正しました 12/22 09:37

@Table(name = "parent_table")
@Entity
public class Parent implements Serializable {
    private static final long serialVersionUID = 8058371942878604902L;
    @EmbeddedId
    private ParentKey parentKey = new parentKey();
    @Column(name = "parent_name")
    private String parentName;
    @OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
    @JoinColumn(name = "parent_id", referencedColumnName = "parent_id")
    @NotFound(action=NotFoundAction.IGNORE)
    private List<Child> childList;

    /** getter,setter省略 **/

    public static class ParentKey implements Serializable {
        private static final long serialVersionUID = -795173904285910114L;
        @Column(name = "hoge_id")
        String hogeId;
        @Column(name = "parent_id")
        String parentId;
    }

    /** equals,hashCode省略 **/
}

@Table(name = "child_table")
@Entity
public class Child implements Serializable {
    private static final long serialVersionUID = 1718966005562173513L;
    @EmbeddedId
    private ChildKey childKey = new childKey();
    @Column(name = "child_name")
    private String childName;
    @ManyToOne
    @JoinColumn(name = "parent_id", referencedColumnName = "parent_id")
    private Parent parent;

    /** getter,setter省略 **/

    public static class ChildKey implements Serializable {
        private static final long serialVersionUID = -3848325403357861609L;
        @Column(name = "child_id")
        String childId;
        @Column(name = "parent_id")
        String parentId;
    }

    /** equals,hashCode省略 **/
}

発生している問題・エラーメッセージ

上記の状態で、起動すると下記のエラーが出ます。

Caused by: org.hibernate.AnnotationException: referencedColumnNames(parent_id) of xx.xx.xxx.Child.parent referencing xx.xx.xxx.Parent not mapped to a single property

もう二日くらい悩んでおります・・・
やっぱJPAやめようかな

補足情報(言語/FW/ツール等のバージョンなど)

必要そうなものだけ
java8
spring boot 1.3.0.RELEASE
spring-data-jpa-1.9.1.RELEASE
hibernate-jpa-2.1-api-1.0.0.Final

  • 気になる質問をクリップする

    クリップした質問は、後からいつでもマイページで確認できます。

    またクリップした質問に回答があった際、通知やメールを受け取ることができます。

    クリップを取り消します

  • 良い質問の評価を上げる

    以下のような質問は評価を上げましょう

    • 質問内容が明確
    • 自分も答えを知りたい
    • 質問者以外のユーザにも役立つ

    評価が高い質問は、TOPページの「注目」タブのフィードに表示されやすくなります。

    質問の評価を上げたことを取り消します

  • 評価を下げられる数の上限に達しました

    評価を下げることができません

    • 1日5回まで評価を下げられます
    • 1日に1ユーザに対して2回まで評価を下げられます

    質問の評価を下げる

    teratailでは下記のような質問を「具体的に困っていることがない質問」、「サイトポリシーに違反する質問」と定義し、推奨していません。

    • プログラミングに関係のない質問
    • やってほしいことだけを記載した丸投げの質問
    • 問題・課題が含まれていない質問
    • 意図的に内容が抹消された質問
    • 広告と受け取られるような投稿

    評価が下がると、TOPページの「アクティブ」「注目」タブのフィードに表示されにくくなります。

    質問の評価を下げたことを取り消します

    この機能は開放されていません

    評価を下げる条件を満たしてません

    評価を下げる理由を選択してください

    詳細な説明はこちら

    上記に当てはまらず、質問内容が明確になっていない質問には「情報の追加・修正依頼」機能からコメントをしてください。

    質問の評価を下げる機能の利用条件

    この機能を利用するためには、以下の事項を行う必要があります。

質問への追記・修正、ベストアンサー選択の依頼

  • 退会済みユーザー

    退会済みユーザー

    2015/12/22 10:40 編集

    修正ありがとうございます。ただ、まだ疑問点が残りましたので記載します。
    【1】ParentのPKは(hoge_id,parent_id)の複合キーとなっていますが、書かれているSQL文のJOINの条件はparent_idのみです。@OneToManyアノテーションがついていますが、実際にはmany-to-manyということでしょうか。
    【2】Childの複合PKも(child_id, parent_id)となっており、many-to-manyを示唆しています(many-to-oneであればhoge_idも必要であるはず)。あるいは、parent_idが単独でユニークになるのであればmany-to-oneは成立します、が、その場合ParentのPKは(parent_id)のみということになります。どちらが正しいでしょうか。////質問文をそのまま解釈すると、JPAの問題以前の、FK設計(あるいはPK設計)に問題があるように見えます。該当エラーメッセージは、複数カラムを使用するJOINに対しては@JoinColumns(最後のsに注意)を使用しなければならない、というエラーですが、本質はそこではありません。

    キャンセル

  • shiva768

    2015/12/22 11:05

    parent_idのみでのjoinがしたいので、@ManyToManyになるが正しいです。なるほど、アノテーションの付け方が誤っていたのですね。

    キャンセル

  • 退会済みユーザー

    退会済みユーザー

    2015/12/22 11:14 編集

    すみません、書き方が悪かったですが、「parent_idのみでのjoinがしたい」のであればmany-to-manyにすべきだ、と言っているわけではなく、本来はどっちなのだろうか、というのがコードからは分からないということです。ParentがListでChildを持っており、他方、Childがparentフィールドで1インスタンスのみをもつようなクラス設計にしているということはone-to-manyなのだろうという想像はつく(し、それが一般的)のですが、テーブル設計がそうなっているようには見えない、のでどっちが正しいのだろう、と。本当にmany-to-manyが正しいのであれば、JPAアノテーションの問題のみならず、クラス設計から間違っています(ChildもListでParentを持たなければならないかと)。

    キャンセル

  • shiva768

    2015/12/22 11:36

    テーブル設計が正しいようですので、many-to-manyが正しいです。
    大変お恥ずかしいですが、yukihaneさんの仰る通りクラス設計が誤っていました。

    キャンセル

回答 2

checkベストアンサー

+1

@JoinColumn(name = "parent_id", referencedColumnName = "parent_id")

ここで問題あるかと思います。

参考:
http://stackoverflow.com/questions/21536095/org-hibernate-annotationexception-referencedcolumnnames-referencing-not-mapped

cause:
The cause of the issue is that you are trying to use a single join column, while the identity of the referenced entity is defined by multiple columns. You simply have to define all the needed join colums and you are good to go:

google翻訳:
問題の原因は、参照エンティティのアイデンティティが複数の列で定義されているときに、単一の結合列を使用しようとしているということです。あなたは、単にすべての参加に必要なcolumsを定義する必要があり、あなたが行ってもいいです。(なんとなくわかる)

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

  • 2015/12/22 16:05

    ご回答ありがとうございます。
    「情報の追加・修正の依頼」でのyukihaneさんとのやりとりの結果、クラス設計のミスということになりました。
    one-to-manyしたいのであれば、oneに当たるテーブルのPKをJoinColumnに全て指定しなければならないということですね。
    ありがとうございます。

    キャンセル

0

解決はしてないんですが
「情報の追加・修正の依頼」でのyukihaneさんとの会話の結果、そもそもクラス設計が間違っていたようです。実際にはテーブル設計も微妙なんですが、いまさらどうこう出来るものでもないのでそれは置いておきます。
とりあえず、似たようなことがやりたくてココにたどり着いちゃった人は

one-to-manyで結合したければ、oneにあたるクラスのPKは全てjoinに含めましょう!含めれない場合は、クラス設計のミスかテーブル設計がおかしい場合があるっぽい?
many-to-oneも一緒
many-to-manyはよくわかりません。中間テーブルがいるっぽいけど、このPJは中間テーブルないんだよなー

投稿

  • 回答の評価を上げる

    以下のような回答は評価を上げましょう

    • 正しい回答
    • わかりやすい回答
    • ためになる回答

    評価が高い回答ほどページの上位に表示されます。

  • 回答の評価を下げる

    下記のような回答は推奨されていません。

    • 間違っている回答
    • 質問の回答になっていない投稿
    • スパムや攻撃的な表現を用いた投稿

    評価を下げる際はその理由を明確に伝え、適切な回答に修正してもらいましょう。

同じタグがついた質問を見る

  • Java

    15108questions

    Javaは、1995年にサン・マイクロシステムズが開発したプログラミング言語です。表記法はC言語に似ていますが、既存のプログラミング言語の短所を踏まえていちから設計されており、最初からオブジェクト指向性を備えてデザインされています。セキュリティ面が強力であることや、ネットワーク環境での利用に向いていることが特徴です。Javaで作られたソフトウェアは基本的にいかなるプラットフォームでも作動します。

  • Spring

    787questions

    Spring Framework は、Javaプラットフォーム向けのオープンソースアプリケーションフレームワークです。 Java Platform上に、 Web ベースのアプリケーションを設計するための拡張機能が数多く用意されています。

  • Spring Boot

    664questions

    Spring Bootは、Javaのフレームワークの一つ。Springプロジェクトが提供する様々なフレームワークを統合した、アプリケーションを高速で開発するために設計されたフレームワークです。

  • Hibernate

    41questions

    HibernateとはJava言語のobject-relational mapping (ORM)ライブラリであり、Object/Relational Mappingよりはるか多くの方法でアプリケーションをPOJOで機能付けることができます。