2012-03-10 2 views
18

В классе Родитель есть список List. Когда родитель сохраняется, дети, которые были добавлены или изменены, должны быть сохранены/обновлены спящим режимом.Спящий режим: OneToMany спасите детей по каскаду

Я нашел много объяснений по этому вопросу, однако, я просто не могу заставить его работать.

Parent.class попробовать

@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 попробовать 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; 

дети добавляют к новому родителю. После этого оба спасены

sessionFactory.getCurrentSession().saveOrUpdate(parent); 

при промывке, однако, я получаю следующее сообщение об ошибке:

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) 

ли кто-нибудь увидеть свою ошибку?

Спасибо вам большое!

+2

опубликовать код для ** child ** и как вы строите объекты, befo re сохранить. – ManuPK

ответ

13

Я думаю, если вы ответить на вопрос из первого комментария, мы пришли к такой ситуации:

  • , вы имеете уже сохранялись родителем
  • у вас есть новые дочерние объекты, которые еще не были сохранялось
  • добавить детей к родителю и сделать saveOrUpdate

в этом случае зимуют только каскады сохранения или обновления для детей, но они не могут быть сохранены или обновлены они еще не настойчивы. И теперь Hibernate просто говорит: «Я не могу обновить несуществующую сущность»

В одном предложении: Hibernate только каскадирует то, что выдается каскаду. В этом случае вы выдаете «SAVE_UPDATE», который затем каскадируется потом детям. Думаю, вы ожидали, что Hibernate будет умным и переключится на детей здесь. Но здесь не работает Hibernate, я тоже сталкивался с подобными ситуациями. Немного сбивает с толку, но если вы когда-нибудь узнаете, как работает каскадный процесс, вы увидите такие ситуации.

5

Мне нужен был способ вставить объект с новым объединенным (дочерним) объектом вместе. Один из способов сделать это - разделить действия (например, сначала сохранить объединенный объект, а затем сохранить основной объект). Однако поддержка Hibernate вставляет новый объект с новым объединенным объектом. См. Один пример: How to insert OneToMany children by cascade

6

Ваш Parent.class try A кажется уже правильным. Но чтобы каскадировать ребенка при сохранении родителя, вы должны поставить каскад на стороне владельца (в один ко многим, это сущность с внешним ключом).

Попробуйте

@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 нуль/пусто

Смежные вопросы