2012-03-10 26 views
18

Trong lớp cha mẹ có danh sách danh sách. Khi cha mẹ được lưu, những đứa trẻ đã được thêm vào hoặc thay đổi sẽ được lưu/cập nhật bởi hibernate.Hibernate: OneToMany lưu trẻ em theo tầng thác

Tôi đã tìm thấy nhiều giải thích về điều này, tuy nhiên, tôi không làm cho nó hoạt động.

Parent.class thử Một

@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 thử B

@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; 

trẻ em được bổ sung cho phụ huynh mới. Sau đó cả hai được cứu bởi

sessionFactory.getCurrentSession().saveOrUpdate(parent); 

khi bốc hỏa, mặc dù, tôi nhận được lỗi sau:

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) 

Có ai thấy sai lầm của tôi?

Cảm ơn bạn rất nhiều !!

+2

xuất bản mã cho ** con ** và cách bạn đang xây dựng các đối tượng, befo tái lưu. – ManuPK

Trả lời

13

Tôi đoán nếu bạn trả lời các câu hỏi từ những nhận xét đầu tiên, chúng tôi sẽ đến tình trạng này:

  • bạn có một đã tồn mẹ
  • bạn có các đối tượng trẻ mới, mà chưa được kiên
  • bạn thêm trẻ em cho phụ huynh và làm saveOrUpdate

Trong trường hợp đó ngủ đông chỉ thác các lưu hoặc cập nhật cho trẻ em, nhưng họ không thể được lưu hay cập nhật khi họ vẫn chưa kiên trì. Và bây giờ Hibernate nói đơn giản là "Tôi không thể cập nhật một thực thể không liên tục"

Trong một câu: Hibernate chỉ xếp thứ tự những gì nó được phát hành để xếp tầng. Trong trường hợp này, bạn phát hành "SAVE_UPDATE", sau đó được xếp chồng lên nhau cho trẻ em. Tôi đoán bạn mong đợi Hibernate là thông minh và chuyển sang tồn tại cho trẻ em ở đây. Nhưng đây không phải là cách Hibernate hoạt động ở đây, tôi cũng đã từng gặp những tình huống tương tự trước đây. Một chút bối rối, nhưng nếu bạn đã từng làm việc như thế nào tầng, bạn sẽ thấy tình huống như vậy.

5

Tôi cần một cách để chèn thực thể với thực thể mới (trẻ em) đã tham gia cùng nhau. Một cách để làm điều đó là bằng cách tách riêng các hành động (ví dụ: để lưu thực thể được nối trước và sau đó để lưu thực thể chính). Tuy nhiên, hỗ trợ Hibernate chèn một thực thể mới với thực thể được kết hợp mới. Xem một ví dụ về cách thức: How to insert OneToMany children by cascade

6

Parent.class try A dường như đã chính xác. Nhưng để thác các con trong khi lưu cha mẹ, bạn phải đặt thác trên phía chủ sở hữu (trong một-nhiều, nó là thực thể có khóa ngoại).

Hãy thử điều này

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

và trẻ em của bạn.lớp

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

Hãy thử điều này:

@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; 
} 

Cách sử dụng

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); 
} 

Lưu ý: Đừng quên để thiết lập các mẹ vào đối tượng trẻ em hoặc bạn sẽ nhận được TABLE_CHILD.PARENT_ID null/trống

Các vấn đề liên quan