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

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

ただいまの
回答率

87.37%

Spring JPAで複合主キーを設定して起動するにはどうしたらよいのでしょうか?

解決済

回答 1

投稿 編集

  • 評価
  • クリップ 0
  • VIEW 2,738

score 67

Spring JPAで複合主キーを設定して起動するにはどうしたらよいのでしょうか?

https://qiita.com/shotana/items/906d0596ce152fe3c6c1を参考にやってみたのですが、できません。
QuestionPkcの各フィールドに@Embeddedを付与しても同じエラーで起動できません。
どこを修正すればよいのでしょうか?

Error starting ApplicationContext. To display the conditions report re-run your application with 'debug' enabled.
2020-02-25 21:50:26.150 ERROR 12888 --- [           main] o.s.boot.SpringApplication               : Application run failed

org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'entityManagerFactory' defined in class path resource [org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]: Invocation of init method failed; nested exception is org.hibernate.AnnotationException: Unable to find properties (timeSegment, period, questionNo, yearNumber, examinationYear) in entity annotated with @IdClass:com.koikeya.project1.domain.model.Question
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1782)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:593)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:515)
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:320)
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:222)
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:318)
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
    at org.springframework.context.support.AbstractApplicationContext.getBean(AbstractApplicationContext.java:1105)
    at org.springframework.context.support.AbstractApplicationContext.finishBeanFactoryInitialization(AbstractApplicationContext.java:867)
    at org.springframework.context.support.AbstractApplicationContext.refresh(AbstractApplicationContext.java:549)
    at org.springframework.boot.web.servlet.context.ServletWebServerApplicationContext.refresh(ServletWebServerApplicationContext.java:142)
    at org.springframework.boot.SpringApplication.refresh(SpringApplication.java:782)
    at org.springframework.boot.SpringApplication.refreshContext(SpringApplication.java:404)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:319)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1275)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1263)
    at com.koikeya.project1.Project1Application.main(Project1Application.java:18)
Caused by: org.hibernate.AnnotationException: Unable to find properties (timeSegment, period, questionNo, yearNumber, examinationYear) in entity annotated with @IdClass:com.koikeya.project1.domain.model.Question
    at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:1003)
    at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:802)
    at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:254)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:230)
    at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:273)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:900)
    at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:931)
    at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:57)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.createNativeEntityManagerFactory(LocalContainerEntityManagerFactoryBean.java:365)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.buildNativeEntityManagerFactory(AbstractEntityManagerFactoryBean.java:390)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.afterPropertiesSet(AbstractEntityManagerFactoryBean.java:377)
    at org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean.afterPropertiesSet(LocalContainerEntityManagerFactoryBean.java:341)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1841)
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1778)
    ... 16 common frames omitted
/**
 * 問題エンティティクラス
 *
 * @author Yuki Koike
 */
@Data
@Entity
@IdClass(QuestionPkc.class)
@Table(name = "QUESTION")
public class Question {

    /**
     * 問題マスタ主キー
     */
    @EmbeddedId
    private QuestionPkc questionPkc;

    /**
     * 問題文
     */
    @Column(name = "SENTENCE_OF_QUESTION")
    private String sentenceOfQuestion;

    /**
     * 選択肢ア
     */
    @Column(name = "FIRST_OPINION")
    private String firstOpinion;

    /**
     * 選択肢イ
     */
    @Column(name = "SECOND_OPINION")
    private String secondOpinion;

    /**
     * 選択肢ウ
     */
    @Column(name = "THIRD_OPINION")
    private String thirdOpinion;

    /**
     * 選択肢エ
     */
    @Column(name = "FOURTH_OPINION")
    private String fourthOpinion;

    /**
     * 更新日時
     */
    @Column(name = "UPDATED_AT", insertable = false, updatable = false)
    private String updatedAt;

    /**
     * 登録日時
     */
    @Column(name = "CREATED_AT", insertable = false)
    private String createdAt;

    /**
     * 版
     */
    @Version
    @Column(name = "VERSION", insertable = false)
    private int version;
}
/**
 * 問題マスタ主キー定義クラス
 *
 * @author Yuki Koike
 *
 */
@Data
@Embeddable
public class QuestionPkc implements Serializable {

    /**
     * 年号
     */
    @Embedded
    @Column(name = "YEAR_NUMBER")
    private String yearNumber;

    /**
     * 年
     */
    @Column(name = "EXAMINATION_YEAR")
    private String examinationYear;

    /**
     * 期
     */
    @Column(name = "PERIOD")
    private String period;

    /**
     * 時間区分
     */
    @Column(name = "TIME_SEGMENT")
    private String timeSegment;

    /**
     * 問題番号
     */
    @Column(name = "QUESTION_NO")
    private String questionNo;
}
  • 気になる質問をクリップする

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

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

    クリップを取り消します

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

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

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

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

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

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

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

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

    質問の評価を下げる

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

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

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

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

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

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

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

    詳細な説明はこちら

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

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

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

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

  • asahina1979

    2020/02/26 09:00

    どう作るかわからないなら hibernate tools

    キャンセル

  • yuki1111

    2020/02/28 01:47

    hibernate toolsが僕が使っているeclipseのバージョン(Photon Release (4.8.0))に対応していなかったので、ググりながら自力で解決しました。しかし使えたら便利ですねhibernate tools。ありがとうございます。

    キャンセル

  • asahina1979

    2020/02/28 15:34

    maven-plugin / ant 実行なら eclipse のバージョンは関係なし

    キャンセル

  • yuki1111

    2020/03/14 01:56

    ありがとうございます。
    ググッたら設定のやりかた(英語だけど)も出てきたので明日か明後日にトライしてみます。
    http://www.javawebtutor.com/articles/maven/maven_hibernate_example.php

    キャンセル

回答 1

check解決した方法

0

下記のように実装したらできました。

参考

  • http://www.thejavageek.com/2014/05/01/jpa-idclass-example/
  • https://jpn.itlibra.com/article?id=20734
package com.koikeya.project1.domain.model;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.IdClass;
import javax.persistence.Table;
import javax.persistence.Version;

import lombok.Data;

/**
 * 問題エンティティクラス
 *
 * @author Yuki Koike
 */
@Data
@Entity
@IdClass(QuestionPkc.class)
@Table(name = "QUESTION")
public class Question {

    /**
     * 年号
     */
    @Id
    @Column(name = "YEAR_NUMBER")
    private String yearNumber;

    /**
     * 年
     */
    @Id
    @Column(name = "EXAMINATION_YEAR")
    private String examinationYear;

    /**
     * 期
     */
    @Id
    @Column(name = "PERIOD")
    private String period;

    /**
     * 時間区分
     */
    @Id
    @Column(name = "TIME_SEGMENT")
    private String timeSegment;

    /**
     * 問題番号
     */
    @Id
    @Column(name = "QUESTION_NO")
    private String questionNo;

    /**
     * 問題文
     */
    @Column(name = "SENTENCE_OF_QUESTION")
    private String sentenceOfQuestion;

    /**
     * 選択肢ア
     */
    @Column(name = "FIRST_OPINION")
    private String firstOpinion;

    /**
     * 選択肢イ
     */
    @Column(name = "SECOND_OPINION")
    private String secondOpinion;

    /**
     * 選択肢ウ
     */
    @Column(name = "THIRD_OPINION")
    private String thirdOpinion;

    /**
     * 選択肢エ
     */
    @Column(name = "FOURTH_OPINION")
    private String fourthOpinion;

    /**
     * 更新日時
     */
    @Column(name = "UPDATED_AT", insertable = false, updatable = false)
    private String updatedAt;

    /**
     * 登録日時
     */
    @Column(name = "CREATED_AT", insertable = false)
    private String createdAt;

    /**
     * 版
     */
    @Version
    @Column(name = "VERSION", insertable = false)
    private int version;
}
package com.koikeya.project1.domain.model;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;

import lombok.Data;

/**
 * 問題マスタ主キー定義クラス
 *
 * @author Yuki Koike
 *
 */
@Data
@Embeddable
public class QuestionPkc implements Serializable {

    /**
     * 年号
     */
    @Column(name = "YEAR_NUMBER")
    private String yearNumber;

    /**
     * 年
     */
    @Column(name = "EXAMINATION_YEAR")
    private String examinationYear;

    /**
     * 期
     */
    @Column(name = "PERIOD")
    private String period;

    /**
     * 時間区分
     */
    @Column(name = "TIME_SEGMENT")
    private String timeSegment;

    /**
     * 問題番号
     */
    @Column(name = "QUESTION_NO")
    private String questionNo;
}
package com.koikeya.project1.domain.repository;

import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.data.repository.query.Param;

import com.koikeya.project1.domain.model.Question;

/**
 * 問題リポジトリインタフェース
 *
 * @author Yuki Koike
 */
public interface QuestionRepository extends JpaRepository<Question, String>{

    @Query("SELECT question FROM Question question WHERE question.yearNumber = :yearNumber AND"
      + " question.examinationYear = :examinationYear AND question.period = :period AND"
      + " question.timeSegment = :timeSegment AND question.questionNo = :questionNo")
    Question findByCompositePrimaryKey(
      @Param("yearNumber")String yearNumber, @Param("examinationYear")String examinationYear,
      @Param("period")String period, @Param("timeSegment")String timeSegment, @Param("questionNo")String questionNo);

}

投稿

  • 回答の評価を上げる

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

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

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

  • 回答の評価を下げる

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

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

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

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

  • ただいまの回答率 87.37%
  • 質問をまとめることで、思考を整理して素早く解決
  • テンプレート機能で、簡単に質問をまとめられる

関連した質問

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