简体   繁体   English

在OneToMany中使用Hibernate持久化对象

[英]Persist Object with Hibernate in OneToMany

I have a problem with my hibernate casscade. 我的休眠级联有问题。 I'm trying to persist a set of document. 我正在尝试保留一组文档。 The data model is the following: 数据模型如下:

  • Corpus 1 --- n Document 1 --- n TextBlock n --- 1 Speaker n --- 1 Party 语料库1 --- n文档1 --- n TextBlock n --- 1演讲者n- 1派对

My scenario is the following: 我的情况如下:

SpeakerFacade sf = new SpeakerFacade();
TextBlockFacade tf = new TextBlockFacade();

Corpus corpus = new Corpus();

Document doc1 = new Document(corpus);
TextBlock tb1 = new TextBlock(new Speaker("David", "Müller", new Party("ASDF")), "TB1", doc1);
tf.createTextBlock(tb1);
TextBlock tb2 = new TextBlock(new Speaker("Benedikt", "Müller", new Party("JKLÖ")), "TB2", doc1);
tf.createTextBlock(tb2);
TextBlock tb3 = new TextBlock(sf.findPersonById(1), "TB3", doc1);
tf.createTextBlock(tb3);

So in the first block I create a new TextBlock. 因此,在第一步中,我创建了一个新的TextBlock。 With the cascade the rest should be created too. 对于级联,其余的也应创建。 In the second block I create another textblock within the same document. 在第二个块中,我在同一文档中创建另一个文本块。 In the last block I create also antoher textblock but with the same speaker. 在最后一个块中,我还创建了另一个文本块,但使用了相同的扬声器。 But I constantly getting the following exception: 但是我不断收到以下异常:

Caused by: org.hibernate.TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing : de.uniba.speechanalyser.persist.model.Document.corpus -> de.uniba.speechanalyser.persist.model.Corpus

Here you can see my model classes (in short form): 在这里,您可以看到我的模型类(简写形式):

Corpus Class 语料库类

@Entity
public class Corpus implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "corpus_id")
private int id;

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "corpus")
private List<Document> documentList;
}

Document Class 文件类别

@Entity
public class Document implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "document_id")
private int id;

@ManyToOne(cascade = { CascadeType.MERGE },fetch= FetchType.EAGER)
private Corpus corpus;

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "document")
private List<TextBlock> textBlockList;
}

TextBlock Class TextBlock类

@Entity
public class TextBlock implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "textblock_id")
private int id;

@Lob
String content;

@ManyToOne(cascade = { CascadeType.MERGE },fetch= FetchType.EAGER)
private Document document;

@ManyToOne(cascade = { CascadeType.MERGE },fetch= FetchType.EAGER)
private Speaker speaker;
}

Speaker Class 演讲者班

@Entity
@NamedQueries({
    @NamedQuery(name = "Speaker.findSpeakerByName", query = "select s from Speaker s where s.firstName = :firstName and s.lastName = :lastName") })
public class Speaker implements Serializable {

private static final long serialVersionUID = 1L;
public static final String FIND_BY_NAME = "Speaker.findSpeakerByName";

@Id
@GeneratedValue
@Column(name = "speaker_id")
private int id;

private String firstName;
private String lastName;

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "speaker")
private List<TextBlock> textBlock;

@ManyToOne(cascade = { CascadeType.MERGE },fetch= FetchType.EAGER)
private Party party;
}

Party Class 派对班

@Entity
@NamedQueries({
@NamedQuery(name = "Party.findPartyByName", query = "select p from Party p where p.name = :name")
})

public class Party implements Serializable {

private static final long serialVersionUID = 1L;
public static final String FIND_BY_NAME = "Party.findPartyByName";

@Id
@GeneratedValue
@Column(name = "party_id")
private int id;

private String name;

@OneToMany(cascade = { CascadeType.ALL}, mappedBy = "party")
private List<Speaker> speakerList;
}

I'm also strugeling with the relations between the object/tables. 我也为对象/表之间的关系而苦恼。 Especially with the cascades. 特别是与小瀑布。 I read a lot on stackoverflow but nothing helped really. 我在stackoverflow上读了很多书,但没有任何帮助。 This is my current approach. 这是我目前的做法。 When a create each object on it's own like: 当自己创建每个对象时,就像这样:

Speaker speaker= new Speaker("David", "Müller", pf.findById(1));
sf.createSpeaker(speaker);
speaker = sf.findSpeakerById(1);

And then add it to the TextBlock it works without any problem. 然后将其添加到TextBlock,它可以正常工作。 So can somebody help me? 那有人可以帮我吗?

Greeting, David 大卫问候

Your Corpus does not get persisted. 您的Corpus不会持续存在。 You cascade only MERGE. 您只能级联MERGE。 See the annotation definition in your Document class: 请参阅Document类中的注释定义:

@ManyToOne(cascade = { CascadeType.MERGE }, fetch= FetchType.EAGER)
private Corpus corpus;

should be: 应该:

@ManyToOne(cascade = { CascadeType.MERGE, CascadeType.PERSIST }, fetch= FetchType.EAGER)
//you can simply say CascadeType.ALL if you are sure what you are doing
private Corpus corpus;

Ok, cool I narrowed the problem to only the Speaker-Party-Side of the Relations! 好的,很酷,我将问题缩小到关系的议长方。

My actual new classes are: Corpus Class 我实际的新课程是: 语料库课程

@Entity
public class Corpus implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "corpus_id")
private int id;

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "corpus")
private List<Document> documentList = new ArrayList<Document>();

public void addDocument(Document document) {
    if (documentList != null) {
        documentList.add(document);
    }
}
}

Document Class 文件类别

@Entity
public class Document implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "document_id")
private int id;

@ManyToOne
@JoinColumn(name = "corpus_id")
private Corpus corpus;

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "document")
private List<TextBlock> textBlockList = new ArrayList<TextBlock>();

public Document() {

}

public Document(Corpus corpus) {
    this.corpus = corpus;
}

public void addTextBlock(TextBlock textBlock) {
    if (textBlockList != null) {
        textBlockList.add(textBlock);
    }
}
}

TextBlock Class TextBlock类

@Entity

public class TextBlock implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue
@Column(name = "textblock_id")
private int id;

@Lob
String content;

@ManyToOne
@JoinColumn(name = "document_id")
private Document document;

@ManyToOne
private Speaker speaker;

public TextBlock() {

}

public TextBlock(Speaker speaker, String content, Document document) {
    this.speaker = speaker;
    this.content = content;
    this.document = document;
}
}

Speaker Class 演讲者班

@Entity
@NamedQueries({
    @NamedQuery(name = "Speaker.findSpeakerByName", query = "select s from Speaker s where s.firstName = :firstName and s.lastName = :lastName") })

public class Speaker implements Serializable {

private static final long serialVersionUID = 1L;
public static final String FIND_BY_NAME = "Speaker.findSpeakerByName";

@Id
@GeneratedValue
@Column(name = "speaker_id")
private int id;

private String firstName;
private String lastName;

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "speaker")
private List<TextBlock> textBlock;

@ManyToOne
private Party party;

public Speaker() {

}

public Speaker(String firstName, String lastName, Party party) {
    this.firstName = firstName;
    this.lastName = lastName;
    this.party = party;
}
}

Party Class 派对班

@Entity
@NamedQueries({
@NamedQuery(name = "Party.findPartyByName", query = "select p from Party p where p.name = :name")})

public class Party implements Serializable {

private static final long serialVersionUID = 1L;
public static final String FIND_BY_NAME = "Party.findPartyByName";

@Id
@GeneratedValue
@Column(name = "party_id")
private int id;

private String name;

@OneToMany(cascade = { CascadeType.ALL }, mappedBy = "party")
private List<Speaker> speakerList = new ArrayList<Speaker>();

public Party() {

}

public Party(String name) {
    this.name = name;
}
}

How do I set the CascadeType on Speaker and Party that when I persist a Corpus the Speaker and the Party is persited too. 我如何在“演讲者和聚会”上设置CascadeType,当我保留语料库时,“演讲者和聚会”也保持不变。

My test code is the following: 我的测试代码如下:

CorpusFacade cf = new CorpusFacade();

Corpus corpus = new Corpus();
Document document = new Document(corpus);
corpus.addDocument(document);

Party party = new Party("ASDF");
Speaker speaker = new Speaker("David", "Müller", party);

TextBlock textBlock1 = new TextBlock(speaker, "TB1", document);
document.addTextBlock(textBlock1);
TextBlock textBlock2 = new TextBlock(speaker, "TB1", document);
document.addTextBlock(textBlock2);

cf.createCorpus(corpus);

Edit For those who are interessted in my solution of the problem. 编辑对于那些对我的问题感兴趣的人。 I create first a new Speaker and a new Party. 我首先创建一个新的演讲者和一个新的聚会。 Then I persist the Party (the Speaker persists automatically). 然后我坚持党(议长自动坚持)。 After that I add the Speaker to the TextBlock. 之后,我将Speaker添加到TextBlock。 Thats all. 就这样。 I couldn't find asolution where the corpus creates the Speaker and Party too. 我找不到一个解决方案,即语料库也创建了演讲者和聚会。 I hope it works for someone. 我希望它对某人有用。

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

相关问题 无法在HIbernate 4中保持OneToMany关系 - Unable to persist OneToMany relationship in HIbernate 4 使用JPA(hibernate)和简单的oneToMany无法持久保存新的对象图 - ManyToOne关系 - Unable to persist new object graph using JPA (hibernate) with simple oneToMany - ManyToOne relationship Hibernate / JPA使用生成的UUID持久保存OneToMany对象 - Hibernate/JPA persist OneToMany objects with generated UUID's Hibernate试图保留错误的对象 - Hibernate trying to persist the wrong object 仅带有 id 的 HIbernate 持久对象 - HIbernate persist object only with id 在 hibernate 中,是否可以在构造函数中保留 object? - In hibernate, is it possible to persist an object in the constructor? 简单对象保持在Spring +休眠状态 - Simple object persist in Spring + hibernate Hibernate:将现有的子实体添加到具有 OneToMany 双向关系的新实体并持久化(“分离的实体传递给持久化”) - Hibernate: add existing child entity to new entity with OneToMany bidirectional relationship and persist it ('detached entity passed to persist') Hibernate映射:子对象属性上的OneToMany和OneToOne - Hibernate mapping: OneToMany and OneToOne on child object property 在 Hibernate/JPA 中保存一个带有孩子的对象 - @OneToMany - save an object with childs in Hibernate/JPA - @OneToMany
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM