2012-03-10 19 views
18

親クラスにはリストリストがあります。親が保存されると、追加または変更された子は、休止状態で保存/更新されます。Hibernate:OneToManyカスケードで子を保存

私はこれについて多くの説明を見つけましたが、動作させることはできません。

Parent.classは

@Entity 
public class Parent { 
// id and other attributes 
    @OneToMany(mappedBy = "parent", cascade = { javax.persistence.CascadeType.ALL }, 
orphanRemoval = true) 
@org.hibernate.annotations.Cascade({ 
org.hibernate.annotations.CascadeType.PERSIST, 
org.hibernate.annotations.CascadeType.MERGE, 
org.hibernate.annotations.CascadeType.REFRESH, 
org.hibernate.annotations.CascadeType.SAVE_UPDATE, 
org.hibernate.annotations.CascadeType.REPLICATE, 
org.hibernate.annotations.CascadeType.LOCK, 
org.hibernate.annotations.CascadeType.DETACH }) 
protected List<child> children; 

子どもたちが新しい親に追加されたB試みる

@Entity 
public class Parent { 
// id and other attributes 
@OneToMany(mappedBy = "parent") 
@org.hibernate.annotations.Cascade(org.hibernate.annotations.CascadeType.ALL) 
protected List<child> children; 

Parent.classを試してみてください。

org.hibernate.TransientObjectException: object references an unsaved transient instance - save the transient instance before flushing: de.pockettaxi.backend.model.ride.RideSingle 
at org.hibernate.engine.ForeignKeys.getEntityIdentifierIfNotUnsaved(ForeignKeys.java:243) 
at org.hibernate.type.EntityType.getIdentifier(EntityType.java:456) 
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:265) 
at org.hibernate.type.ManyToOneType.isDirty(ManyToOneType.java:275) 
at org.hibernate.type.TypeHelper.findDirty(TypeHelper.java:295) 
at org.hibernate.persister.entity.AbstractEntityPersister.findDirty(AbstractEntityPersister.java:3378) 
at org.hibernate.event.def.DefaultFlushEntityEventListener.dirtyCheck(DefaultFlushEntityEventListener.java:520) 
at org.hibernate.event.def.DefaultFlushEntityEventListener.isUpdateNecessary(DefaultFlushEntityEventListener.java:230) 
at org.hibernate.event.def.DefaultFlushEntityEventListener.onFlushEntity(DefaultFlushEntityEventListener.java:154) 
at org.hibernate.event.def.AbstractFlushingEventListener.flushEntities(AbstractFlushingEventListener.java:219) 
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:99) 
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50) 
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1216) 

は誰もが私のミスを参照しています。その後、両方の

sessionFactory.getCurrentSession().saveOrUpdate(parent); 

洗浄時には、しかし、私は次のエラーを取得することにより、保存されていますか?

ありがとうございます!

+2

** child **のコードを公開し、どのようにオブジェクトを構築しているのか、befo保存し直してください。 – ManuPK

答えて

13

私はあなたが最初のコメントからの質問に答えるならば、我々はこのような状況になるだろうと思います。

  • あなたはすでにあなたがまだ
  • を持続していなかった新しい子オブジェクトを持つ親
  • を持続してきました
  • あなたが親に子を追加し、その場合にはするsaveOrUpdate

を行うだけカスケード子供に保存したり、更新の休止状態が、彼らのように保存または更新することはできません彼らはまだ永続していません。そして今、Hibernateは単純に「私は非永続エンティティを更新できません」と言います。

Hibernateはカスケードするために発行されるものだけをカスケードします。この場合、"SAVE_UPDATE"を発行し、それをカスケードして子にさらに送ります。あなたはHibernateがスマートになり、ここで子供たちのために変わり続けることを期待していたと思います。しかし、これはHibernateがここでどのように動作するかではなく、以前も同様の状況に遭遇しました。ちょっと混乱しますが、カスケーディングがどのように機能するかを知っていれば、そのような状況が見えます。

5

新しい結合(子)エンティティを持つエンティティを一緒に挿入する方法が必要でした。これを行う1つの方法は、アクションを別々にすることです(結合されたエンティティを先に保存してからメインエンティティを保存するなど)。 しかし、Hibernateは、新たに結合されたエンティティを持つ新しいエンティティを挿入することをサポートしています。 1つの例を参照してください。How to insert OneToMany children by cascade

6

あなたのParent.classはすでに正しいと思われます。しかし、親を保存しながら子をカスケードするには、カスケードを所有者側に配置する必要があります(一対多では、それは外部キーを持つエンティティです)。

この

@Entity 
public class Parent { 
    @OneToMany(mappedBy = "parent") 
    protected List<Child> children; 
} 

とあなたの子供にしてみてください。クラス

@Entity 
public class Child { 
    @ManyToOne 
    @Cascade(value={org.hibernate.annotations.CascadeType.ALL}) 
    @JoinColumn(name="PARENT_ID") 
    protected Parent parent; 
} 
1

はこれを試してみてください:

@Entity 
@Table(name = "TABLE_PARENT") 
public class Parent{ 
    @OneToMany(mappedBy="parent", cascade=CascadeType.PERSIST) 
    private List<Child> children; 
} 

@Entity 
@Table(name = "TABLE_CHILD") 
public class Child{ 
    @ManyToOne(fetch=FetchType.LAZY) 
    @JoinColumn(name="PARENT_ID") 
    private Parent parent; 
} 

使用

public void save(){ 
    Parent parent = new Parent(); 
    List<Child> children = new ArrayList<>(); 
    Child child = new Child(); 
    child.setParent(parent); 
    children.add(child); 
    parent.setChildren(children); 

    parentRepository.save(parent); 
} 

注:は、子オブジェクトに親を設定することを忘れないでくださいまたはあなたがTABLE_CHILD.PARENT_IDのヌルを取得します/空の

関連する問題