Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/395.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java hibernate和mappedBy:是否可以在不设置对象之间双向关系的情况下自动设置外键?_Java_Hibernate_Hibernate Mapping_Mappedby - Fatal编程技术网

Java hibernate和mappedBy:是否可以在不设置对象之间双向关系的情况下自动设置外键?

Java hibernate和mappedBy:是否可以在不设置对象之间双向关系的情况下自动设置外键?,java,hibernate,hibernate-mapping,mappedby,Java,Hibernate,Hibernate Mapping,Mappedby,欢迎, 我有两门课:对话和提问。一次谈话有很多问题 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.per

欢迎,

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

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 + "]";
}
}
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>
接下来,创建一个包含这两个问题的问题列表 并设置为conv问题列表:

conv.setQuestions(questions); 
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="conversation")
private Collection<Question> questions = new ArrayList<Question>();
一个it工作正常,因为数据被插入到两个表中, 并且外键对话会话ID已填充:

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

question1.setConversation(conv);
question2.setConversation(conv);
外键设置为NULL。为什么?我们已经在对话问题列表中添加了两个问题:

conv.setQuestions(questions); 
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="conversation")
private Collection<Question> questions = new ArrayList<Question>();
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy=“conversation”)
私人收藏问题=新建ArrayList();
,所以hibernate应该知道这两个问题的对话外键是什么(因为它们位于指定的对话问题列表中)。那么,是否可以避免为每个问题设置对话,而只将问题添加到对话的问题列表中?我应该如何配置实体来实现这一点?或者可能这是不可能的,我们总是需要设定两个方向

所以hibernate应该知道这两个问题的对话外键是什么(因为它们位于指定的对话问题列表中)

如果不使用
setConversation()
指定,任何Hibernate都不应该知道这两个
问题的
对话
,因为它在这里处理对象,而这两个
问题
没有任何指示它们属于哪个
对话

说明:

因为当您仅将这两个
问题
添加到
对话
对象时,此信息在
问题
对象中不可见

这里的另一件事是,
mappedBy
属性指示
object
是映射的所有者,因此如果
mappedBy
侧没有给定的对象,如何进行映射

这就是为什么您应该在
问题
对象中指定
对话
,以便可以通过
休眠
正确评估映射

注意:

建议对
OneToMany
映射使用
,而不是任何其他
集合
,因为此集合不应该有任何重复项,因此您最好将其更改为:

@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy="conversation")
private Set<Question> questions = new HashSet<Question>();
@OneToMany(fetch=FetchType.EAGER,cascade=CascadeType.ALL,mappedBy=“conversation”)
私有集问题=新HashSet();