简体   繁体   English

hibernate @OneToMany 连接表未创建

[英]hibernate @OneToMany join table not being created

I have two tables Quiz and Question which I want to associate with a @OneToMany relationship but the join table is not being created in mysql workbench database.我有两个表 Quiz 和 Question ,我想将它们与@OneToMany关系关联,但连接表没有在 mysql 工作台数据库中创建。 Here are the entities:以下是实体:

Quiz.java测验.java

@Entity
public class Quiz {
    
        // attributes :
    private Integer idQuiz;
    private String quizTopic;

   @OneToMany
   @JoinColumn(name = "quiz_Id")
   private List<Question> questions;

        // constructors 
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "quiz_Id")
    public Integer getIdQuiz() {
        return idQuiz;
    }

    @Column(name = "quiz_topic")
    public String getQuizTopic() {
        return quizTopic;
    }
//setters
}

Question.java Question.java

@Entity
public class Question {

    // attributes
    private Integer idQuestion;
    private String value;
    private String op1;
    private String op2;
    private String op3;
    private String correctAnswer;

// constructors  

// Getters :
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "question_Id")
public Integer getIdQuestion() {
    return idQuestion;
}

@Column(name = "question_value")
public String getValue() {
    return value;
}

@Column(name = "question_op1")
public String getOp1() {
    return op1;
}

@Column(name = "question_op2")
public String getOp2() {
    return op2;
}

@Column(name = "question_op3")
public String getOp3() {
    return op3;
}

@Column(name = "question_op4")
public String getCorrectAnswer() {
    return correctAnswer;
}
 //setters
}

no foreign keys are created没有创建外键

here is what I get after running这是我跑步后得到的

    Hibernate: create table question (question_id integer not null auto_increment, question_op4 varchar(255), question_op1 varchar(255), question_op2 varchar(255), question_op3 varchar(255), question_value varchar(255), primary key (question_id)) engine=InnoDB
Hibernate: create table quiz (quiz_id integer not null auto_increment, quiz_topic varchar(255), primary key (quiz_id)) engine=InnoDB

application.properties:应用程序属性:

spring.main.web-application-type=none
spring.application.ui.title=Quiz
spring.jpa.hibernate.ddl-auto=update
spring.datasource.url=jdbc:mysql://localhost:3306/quiz?createDatabaseIfNotExist=true&useUnicode=true&useJDBCCompliantTimezoneShift=true&useLegacyDatetimeCode=false&serverTimezone=UTC
spring.datasource.username=root
spring.datasource.password=justpass
spring.jpa.show-sql=true

The annotation注释

@OneToMany
private ArrayList<Question> questions;

will not create a join table.不会创建连接表。 It should create a foreign-key in the Question table to the Quiz table.它应该在 Quiz 表的 Question 表中创建一个外键。 This foreign key is not the same as the此外键与

private Integer idQuestion;

column.柱子。

For your solution it dependes wether you want to build a uni- or bidirectional @OneToMany relationship.对于您的解决方案,这取决于您是要建立单向还是双向@OneToMany关系。 If you want a unidirectional one-to-many relationship you have to define a @JoinColumn to tell Hibernate that it shall create a foreign key with the given name in the related table.如果你想要一个单向的一对多关系,你必须定义一个@JoinColumn来告诉 Hibernate 它应该在相关表中创建一个具有给定名称的外键。 Most of the time a unidirectional one to many relationship is the easiest and sufficient way to go.大多数情况下,单向一对多关系是 go 最简单和充分的方法。

Unidirectional单向

@OneToMany
@JoinColumn(name = "quiz_id")
private List<Question> questions;

By this Hibernate will create the foreign key with name " quiz_id " in the question table.通过这个 Hibernate 将在问题表中创建名为“ quiz_id ”的外键。

In the bidirectional case we are able to access the quiz from the question vice versa the questions from the quiz.在双向情况下,我们可以从问题中访问测验,反之亦然,从测验中访问问题。 In this case you will you will have to define the variable which shall represent the parent class in the child class.在这种情况下,您将必须在子 class 中定义代表父 class 的变量。 For example if the quiz shall be the parent class, you will define the annotation.例如,如果测验应该是父 class,您将定义注释。 @OneToMany(mappedBy = "quiz") . @OneToMany(mappedBy = "quiz") Additionally to this you will have to define the question to be the @ManyToOne side as well.除此之外,您还必须将问题定义为@ManyToOne方面。 All in all:总而言之:

Bidirectional双向

Quiz.java:测验.java:

@OneToMany(mappedBy = "quiz")
private List<Question> questions;

Question.java Question.java

@ManyToOne(fetch = FetchType.LAZY)
private Quiz quiz;

You will want to define the fetch type to be lazy due to performance reasons (I even ran into some overflow errors in the past, without the lazy method).由于性能原因,您将希望将 fetch 类型定义为惰性(过去我什至遇到了一些溢出错误,没有惰性方法)。

Keep in mind that if you are using the bidirectional mapping together with serialization libraries such as jackson, you will run into the JSON infinite recursion problem when de-/serializing from/to JSON.请记住,如果您将双向映射与 jackson 等序列化库一起使用,则在从 Z0ECD11C1D7A2877401D148A23F 反序列化/序列化到 Z0ECD11C1D7A287401DZ48A23F 时会遇到JSON 无限递归问题In this case you will want to use @JsonIdentityInfo to serialize the id only instead of the complete entity (which will lead to infinite recursion) or @JsonIgnore respectively @JsonManagedReference and @JsonBackReference to not serialize the child dependencies of an entity.在这种情况下,您将希望使用@JsonIdentityInfo仅序列化 id 而不是完整实体(这将导致无限递归)或@JsonIgnore分别@JsonManagedReference@JsonBackReference来不序列化实体的子依赖项。

I also recommend to use the properties cascade defining the cascade type and orphanRemoval for the deletion of entities when you work with relationships, but I did not want to blow up my answer with unrelated information.我还建议在处理关系时使用定义级联类型的属性cascadeorphanRemoval来删除实体,但我不想用不相关的信息来破坏我的答案。

It looks suspicious that you try to mix up access strategies in the Quiz entity.您尝试在Quiz实体中混合访问策略看起来很可疑。

As it is stated in the documentation :正如文档中所述:

As a JPA provider, Hibernate can introspect both the entity attributes (instance fields) or the accessors (instance properties).作为 JPA 提供者,Hibernate 可以自省实体属性(实例字段)或访问器(实例属性)。 By default, the placement of the @Id annotation gives the default access strategy.默认情况下, @Id注释的位置提供了默认访问策略。 When placed on a field, Hibernate will assume field-based access.放置在字段上时,Hibernate 将采用基于字段的访问。 When placed on the identifier getter, Hibernate will use property-based access.当放置在标识符 getter 上时,Hibernate 将使用基于属性的访问。

So, instead of this:所以,而不是这个:

@OneToMany
@JoinColumn(name = "quiz_Id")
private List<Question> questions;

put the @OneToMany and @JoinColumn(name = "quiz_Id") annotations on the appropriate getter:@OneToMany@JoinColumn(name = "quiz_Id")注释放在适当的 getter 上:

@OneToMany
@JoinColumn(name = "quiz_Id")
public List<Question> getQuestions() {
   return questions;
}

then try to recreate your schema by setting the spring.jpa.hibernate.ddl-auto property like this:然后尝试通过设置spring.jpa.hibernate.ddl-auto属性来重新创建您的架构:

spring.jpa.hibernate.ddl-auto=create

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM