Spring Boot JPA Hibernate:即使实体类中存在@Id,也没有为实体错误指定标识符

Posted

技术标签:

【中文标题】Spring Boot JPA Hibernate:即使实体类中存在@Id,也没有为实体错误指定标识符【英文标题】:Spring Boot JPA Hibernate: No identifier specified for entity error even when @Id is present in the entity class 【发布时间】:2018-10-28 07:05:44 【问题描述】:

我收到“无标识符错误”实体类“QuestionResponse”有两个 @Id 字段。 Question和QuestionResponse之间存在OneToMany关系,Response和QuestionResponse之间存在OnetoMany关系,所有这些类都是基于https://docs.jboss.org/hibernate/orm/5.2/userguide/html_single/Hibernate_User_Guide.html#associations-many-to-many-bidirectional-with-link-entity设计的

我正在使用 Postgres 9.5、Spring Boot 2.0.1 并将其部署在 WildFly 11 上

谢谢!

questions.sql

CREATE TABLE questions( 
    id BIGSERIAL PRIMARY KEY,
    question VARCHAR(255)
);

respones.sql

CREATE TABLE responses( 
    id BIGSERIAL PRIMARY KEY,
    response VARCHAR(255)
);

question_respone.sql #

CREATE TABLE question_response(
    question_id bigint REFERENCES questions ON DELETE CASCADE,
    response_id bigint REFERENCES responses ON DELETE CASCADE,
    PRIMARY KEY ( question_id, response_id)
);

问题.java

@Entity
@Table(name = "questions")
public class Question


    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="qid_seq")
    @SequenceGenerator(name = "qid_seq", sequenceName="questions_id_seq")
    @Column(name = "id")
    private Long id;


    @Column(name = "questionText")
    private String questionText;

    @OneToMany(mappedBy = "question", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<QuestionResponse> responses;

    public Question() 

    public Question(String questionText) 
        super();
        this.questionText = questionText;
    

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public String getQuestionText() 
        return questionText;
    

    public void setQuestionText(String questionText) 
        this.questionText = questionText;
    

    public List<QuestionResponse> getResponses() 
        return responses;
    

QuestionResponse.java

@Entity
@Table(name = "question_response")
public class QuestionResponse 

    @Id
    @ManyToOne 
    private Question question;

    @Id
    @ManyToOne 
    private Response response;



    public QuestionResponse() 
        super();
    

    public QuestionResponse(Question question, Response response) 
        super();
        this.question= question;
        this.response = response;
    

    public Question getQuestion() 
        return question;
    

    public void setQuestion(Question question) 
        this.question = question;
    

    public Response getResponse() 
        return response;
    

    public void setResponse(Response response) 
        this.response = response;
    


Response.java

@Entity
@Table(name = "responses")
public class Response 

    @Id
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="rid_seq")
    @SequenceGenerator(name = "rid_seq", sequenceName="questions_id_seq")
    @Column(name = "id")
    private Long id;

    @Column(name = "responseText")
    private String responseText;

    @OneToMany(mappedBy = "response", cascade = CascadeType.ALL, orphanRemoval = true)
    private List<QuestionResponse> question;

    public Response() 

    public Response(String responseText) 
        super();
        this.responseText = responseText;
    

    public Long getId() 
        return id;
    

    public void setId(Long id) 
        this.id = id;
    

    public String getResponseText() 
        return responseText;
    

    public void setResponseText(String responseText) 
        this.responseText = responseText;
    

    public List<QuestionResponse> getQuestion() 
        return question;
    


WildFly 控制台

13:54:49,581 ERROR [org.springframework.boot.SpringApplication] (ServerService Thread Pool -- 86) 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:
 No identifier specified for entity: com.poc.questionnarie.QuestionResponse

【问题讨论】:

这个问题的任何一个答案都对您有帮助吗? ***.com/questions/41143913/… @geneSummons 我认为它们不适用于我的问题。挑战之一是问题和响应之间的多对多映射。这是通过 QuestionResponse 完成的 “没有为实体指定标识符”错误告诉您编译器没有找到定义的“ID”列,可能是因为您的 QuestionResponse 类/表具有多列主键而不是单列主键。链接问题的答案解释了实现多列主键实体的两种方法。 【参考方案1】:

在 JPA 中,您不能在一个实体中的多个字段上使用 @Id 注释,除非您将其定义为复合主键。因此,您需要将 @IdClass 添加到您的 QuestionResponse 实体中,以便它包含多个主键字段。

这可能与您的问题无关,但也值得一看 article,它显示了将 @ManyToMany 注释与 JPA 结合使用的最佳方式。

【讨论】:

我已经看过这个例子并且没有多大用处,因为我需要向我的 question_response 表写入查询,该表需要有一个实体类。这个例子不满足我的要求 我添加了这个例子只是因为我看到你有一个@MayToMany 关系并认为它可能会对你有所帮助。您的主要问题是因为您在未标记为 @IdClass 的实体中有多个 @Id

以上是关于Spring Boot JPA Hibernate:即使实体类中存在@Id,也没有为实体错误指定标识符的主要内容,如果未能解决你的问题,请参考以下文章

制作多个 EntityManager(Spring-Boot-JPA、Hibernate、MSSQL)

Spring Boot / JPA / Hibernate,如何根据 Spring 配置文件切换数据库供应商?

Spring boot之 JPA/Hibernate/Spring Data

Spring Boot JPA Hibernate - 以毫秒精度存储日期

当加载 spring-boot 和 spring-data-jpa 时,Hibernate 无法加载 JPA 2.1 Converter

Spring Boot 2.1 缺少多个 org.hibernate.jpa.event 类