gpt4 book ai didi

java - hibernate 和映射 : Is it possible to automatically set foreign key without setting bidirectional relationship among objects?

转载 作者:行者123 更新时间:2023-11-30 06:17:49 24 4
gpt4 key购买 nike

欢迎,

我有两门课:对话和问题。一次对话有很多问题。

对话.java:

package com.jcg.jpa.mappedBy;

import java.io.Serializable;
import java.util.ArrayList;
import java.util.Collection;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.Table;

@Entity
@Table(name = "CONVERSATION_TABLE")
public class Conversation implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name = "CONV_ID")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int conversationId;

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

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="conversation")
private Collection<Question> questions = new ArrayList<Question>();

public Conversation() { }

public int getConversationId() {
return conversationId;
}

public void setConversationId(int conversationId) {
this.conversationId = conversationId;
}

public String getName() {
return name;
}

public void setName(String name) {
this.name = name;
}

public Collection<Question> getQuestions() {
return questions;
}

public void setQuestions(Collection<Question> questions) {
this.questions = questions;
}

@Override
public String toString() {
return "Employee [conversationId=" + conversationId + ", name=" + name + "]";
}
}

问题.java:

package com.jcg.jpa.mappedBy;

import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;

@Entity
@Table(name = "QUESTION_TABLE")
public class Question implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@Column(name = "id")
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;

@ManyToOne
@JoinColumn(name = "CONVERSATION_CONV_ID", nullable = false)
private Conversation conversation;


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

@Column(name = "ANSWER_TEXT")
private String answerText;



public Question() { }

public int getId() {
return id;
}

public void setId(int id) {
this.id = id;
}

public String getQuestionText() {
return questionText;
}

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

public String getAnswerText() {
return answerText;
}

public void setAnswerText(String answerText) {
this.answerText = answerText;
}

public Conversation getConversation() {
return conversation;
}

public void setConversation(Conversation conversation) {
this.conversation = conversation;
}

@Override
public String toString() {
return "Question [id=" + id + ", questionText=" + questionText
+ ", answerText=" + answerText +"]";
}
}

持久性.xml:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.1"
xmlns="http://xmlns.jcp.org/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/persistence http://xmlns.jcp.org/xml/ns/persistence/persistence_2_1.xsd">
<persistence-unit name="JPAMappedbyExample" transaction-type="RESOURCE_LOCAL">
<class>com.jcg.jpa.mappedBy.Conversation</class>
<class>com.jcg.jpa.mappedBy.Question</class>

<!-- Configuring The Database Connection Details -->
<properties>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver" />
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/jpatest" />
<property name="javax.persistence.jdbc.user" value="root" />
<property name="javax.persistence.jdbc.password" value="qwerty" />

</properties>
</persistence-unit>

现在在 Main.java 中,我尝试创建包含两个问题的对话:

package com.jcg.jpa.mappedBy;

import java.util.ArrayList;
import java.util.List;

import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

public class Main {

private static final EntityManagerFactory emFactoryObj;
private static final String PERSISTENCE_UNIT_NAME = "JPAMappedbyExample";

static {
emFactoryObj = Persistence.createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
}

// This Method Is Used To Retrieve The 'EntityManager' Object
public static EntityManager getEntityManager() {
return emFactoryObj.createEntityManager();
}

private static void insertRecords() {
EntityManager entityMgrObj = getEntityManager();
if (null != entityMgrObj) {
entityMgrObj.getTransaction().begin();

Conversation conv = new Conversation();
conv.setName("Discussion about something");

Question question1 = new Question();
question1.setQuestionText("2 plus 2");
question1.setAnswerText("four");
question1.setConversation(conv);

Question question2 = new Question();
question2.setQuestionText("what is Your name");
question2.setAnswerText("Adam");
question2.setConversation(conv);

List<Question> questions = new ArrayList<Question>();
questions.add(question1);
questions.add(question2);
conv.setQuestions(questions);

entityMgrObj.persist(conv);
entityMgrObj.getTransaction().commit();

entityMgrObj.clear();
System.out.println("Record Successfully Inserted In The Database");
}
}



public static void main(String[] args) {
insertRecords();

}
}

在 insertRecords() 中,我正在创建转换和两个问题。每个问题都有固定的对话:

question1.setConversation(conv);
question2.setConversation(conv);

接下来,将创建一个包含这 2 个问题的问题列表并设置为转化问题列表:

conv.setQuestions(questions); 

它工作正常,因为数据已插入到两个表中,并且外键 CONVERSATION_CONV_ID 已填充:

conversation_table

question_table

但是,当我删除问题、行中的设置对话时:

question1.setConversation(conv);
question2.setConversation(conv);

外键设置为 NULL。为什么?我们已经在对话问题列表中添加了两个问题:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="conversation")
private Collection<Question> questions = new ArrayList<Question>();

,所以 hibernate 应该知道这两个问题的对话外键是什么(因为它们位于指定的对话问题列表中)。那么是否可以避免为每个问题都设置Conversation,而只将问题添加到Conversation的问题列表中呢?我应该如何配置实体来做到这一点?或者也许这是不可能的,我们总是需要将其设置为两个方向?

最佳答案

so hibernate should know what is conversation foreign key for these two questions (because they are located on specified conversation questions list).

没有 Hibernate 不应该知道 Conversation 是什么?这两个Questions如果您不使用 setConversation() 指定它,因为这里处理的是对象,而这两个 questions没有任何迹象表明 Conversation他们是的一部分。

说明:

因为当你只添加这两个questionsConversation对象,此信息在 Questions 中不可见对象。

这里还有一件事,mappedBy属性表示 object是映射的所有者,那么如果mappedBy中没有给定的对象,如何进行映射呢?侧面?

这就是为什么您应该指定 ConversationQuestion对象,因此可以通过 Hibernate 正确评估映射.

注意:

建议使用Set对于 OneToMany映射而不是任何其他Collection ,因为这个集合不应该有任何重复项,所以你最好将其更改为:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="conversation")
private Set<Question> questions = new HashSet<Question>();

关于java - hibernate 和映射 : Is it possible to automatically set foreign key without setting bidirectional relationship among objects?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48817280/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com