欢迎,
我有2个课:对话和问题。一个对话有很多问题。
Conversation.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 + "]";
}
}
Question.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 +"]";
}
}
的persistence.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()中我创建了conv和两个问题。 每个问题都设置了对话:
question1.setConversation(conv);
question2.setConversation(conv);
接下来,创建包含这两个问题的问题列表 并设置转换问题列表:
conv.setQuestions(questions);
它工作正常,因为数据被插入到两个表中, 并填写外键CONVERSATION_CONV_ID:
但是,当我删除问题中的设置对话时,行:
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的问题列表添加问题?我该如何配置实体呢?或者也许这是不可能的,我们总是需要设置两个方向?
答案 0 :(得分:1)
所以hibernate应该知道这两个问题的对话外键是什么(因为它们位于指定的对话问题列表中)。
如果你没有使用Conversation
来指定它,那么Hibernate不应该知道这两个Questions
的{{1}}是什么,因为它的交易这里有对象,这两个setConversation()
没有任何关于questions
他们所属的指示。
<强>解释强>
因为当您只将这两个Conversation
添加到questions
对象时,此信息在Conversation
个对象中不会显示。
另一件事,Questions
属性指示mappedBy
是映射的所有者,因此如果{{1}中没有给定对象,如何进行映射边?
这就是为什么你应该在object
对象中指定mappedBy
的原因,因此Conversation
可以正确评估映射。
注意:强>
建议使用Question
进行Hibernate
映射而不是任何其他Set
映射,因为此集合不应该有任何重复,因此您最好更改它来:
OneToMany