Подтвердить что ты не робот

Удаленный объект будет повторно сохранен каскадом (удалить удаленный объект из ассоциаций)

i имеет следующие два объекта:

1- PlayList:

@OneToMany(fetch = FetchType.EAGER, mappedBy = "playlist", orphanRemoval = true, cascade =   CascadeType.ALL)
@OrderBy("adOrder")
private Set<PlaylistadMap> PlaylistadMaps = new HashSet<PlaylistadMap>(0);
  • CascadeType.ALL: необходим для сохранения и обновления коллекции PlaylistadMap при сохранении или обновлении объекта списка воспроизведения.
  • orphanRemoval = true: требуется при удалении объекта списка воспроизведения, также должны быть удалены ссылки в PlaylistadMap.

2- PlaylistadMap:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "fk_playlist", referencedColumnName = "pkid", nullable = false)
private Playlist playlist;

при удалении списка воспроизведения с помощью getCurrentSession().delete(); я получаю следующее исключение:

org.springframework.dao.InvalidDataAccessApiUsageException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.xeno.advertisingsuite.web.domain.PlaylistadMap#6]; nested exception is org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.xeno.advertisingsuite.web.domain.PlaylistadMap#6]
    at org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:657)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:793)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:664)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
    at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:393)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
    at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
    at $Proxy54.deletePlayList(Unknown Source)
    at com.xeno.advertisingsuite.web.beans.PlayListBean.deletePlaylist(PlayListBean.java:282)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
    at java.lang.reflect.Method.invoke(Method.java:597)
    at org.apache.el.parser.AstValue.invoke(AstValue.java:262)
    at org.apache.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:278)
    at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:105)
    at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:88)
    ... 103 more
Caused by: org.hibernate.ObjectDeletedException: deleted object would be re-saved by cascade (remove deleted object from associations): [com.xeno.advertisingsuite.web.domain.PlaylistadMap#6]
    at org.hibernate.impl.SessionImpl.forceFlush(SessionImpl.java:1220)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.entityIsTransient(DefaultSaveOrUpdateEventListener.java:188)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.performSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:117)
    at org.hibernate.event.def.DefaultSaveOrUpdateEventListener.onSaveOrUpdate(DefaultSaveOrUpdateEventListener.java:93)
    at org.hibernate.impl.SessionImpl.fireSaveOrUpdate(SessionImpl.java:677)
    at org.hibernate.impl.SessionImpl.saveOrUpdate(SessionImpl.java:669)
    at org.hibernate.engine.CascadingAction$5.cascade(CascadingAction.java:252)
    at org.hibernate.engine.Cascade.cascadeToOne(Cascade.java:392)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:335)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    at org.hibernate.engine.Cascade.cascadeCollectionElements(Cascade.java:425)
    at org.hibernate.engine.Cascade.cascadeCollection(Cascade.java:362)
    at org.hibernate.engine.Cascade.cascadeAssociation(Cascade.java:338)
    at org.hibernate.engine.Cascade.cascadeProperty(Cascade.java:204)
    at org.hibernate.engine.Cascade.cascade(Cascade.java:161)
    at org.hibernate.event.def.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:154)
    at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:145)
    at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
    at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:50)
    at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1206)
    at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:375)
    at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:137)
    at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:656)

пожалуйста, сообщите, как исправить это исключение.

4b9b3361

Ответ 1

проблема решена после изменения FetchType на Lazy

Ответ 2

Решение состоит в том, чтобы точно указать сообщение об ошибке:

Вызвано: org.hibernate.ObjectDeletedException: удаленный объект будет повторно сохранен каскадом (удалить удаленный объект из ассоциаций)

Удалите удаленный объект из ассоциаций (наборов, списков или карт), в которых он находится. В частности, я подозреваю, от PlayList.PlaylistadMaps. Недостаточно просто удалить объект, вам нужно удалить его из любых каскадных коллекций, которые ссылаются на него.

Фактически, поскольку ваша коллекция имеет orphanRemoval = true, вам не нужно ее явно удалять. Вам просто нужно удалить его из набора.

Ответ 3

Я смог решить это, написав код ниже. Я использовал executeUpdate вместо .delete()

def publicSupport = caseObj?.client?.publicSupport
        if(publicSupport)
            PublicSupport.executeUpdate("delete PublicSupport c where c.id = :publicSupportId", [publicSupportId:publicSupport.id])
            //publicSupport.delete()

Ответ 4

Я тоже столкнулся с этим сообщением об исключении. Для меня проблема была другая. Я хотел удалить родителя.

В одной транзакции: Сначала я вызвал родителя из базы данных. Затем я вызвал дочерний элемент из коллекции в родительском элементе. Затем я указал одно поле в дочернем элементе (id) Затем я удалил родителя. Затем я вызвал фиксацию. Я получил ошибку "удаленный объект будет сохранен".

Оказывается, мне пришлось сделать две отдельные транзакции. Я сделал это после ссылки на поле у ​​ребенка. Затем была запущена новая фиксация для удаления.

Не нужно было удалять дочерние элементы или пустые коллекции в родительском (предполагая orphanRemoval = true.). На самом деле это не сработало.

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

Ответ 5

Если вы не знаете, какая коллекция содержит ваш объект

В моем случае было очень сложно применить решение TomAnderson, так как я не знал, что такое коллекция, которая содержит ссылку на объект, поэтому здесь можно узнать, какие объекты содержат ссылку на удаленный: в отладчике вы должны ввести самый низкий уровень стека выполнения перед тем, как будет выбрано исключение, должна быть переменная с именем entityEntry, поэтому вы получаете объект PersistenceContext из этой переменной: entityEntry.persistenceContext.

Для меня PersistenceContext был экземпляром StatefulPersistenceContext, и эта реализация имеет поле private parentsByChild, из которого вы можете получить информацию о коллекции, которая содержит этот элемент.

Я использовал отладчик Eclipse, поэтому было трудно получить это частное поле прямо, поэтому я использовал Detail Formatter (Как посмотреть частные поля других объектов непосредственно в среде IDE при отладке?)

После получения этой информации можно применить решение TomAnderson.

Ответ 6

Вид Начала здесь.

for (PlaylistadMap playlistadMap : playlistadMaps) {
        PlayList innerPlayList = playlistadMap.getPlayList();
        for (Iterator<PlaylistadMap> iterator = innerPlayList.getPlaylistadMaps().iterator(); iterator.hasNext();) {
            PlaylistadMap innerPlaylistadMap = iterator.next();
            if (innerPlaylistadMap.equals(PlaylistadMap)) {
                iterator.remove();
                session.delete(innerPlaylistadMap);
            }
        }
    }

Ответ 7

Поскольку мне нужно FetchType быть EAGER, я удаляю все ассоциации, устанавливая их в (null) и сохраняя объект (который удаляет всю ассоциацию в базе данных), тогда удалите его!

Это добавит несколько миллисекунд, но это хорошо для меня, если есть лучший способ сохранить эти MS, добавьте свой комментарий ниже.

Надеюсь, что помогите кому-то:)

Ответ 8

Я также столкнулся с этой ошибкой в ​​плохо спроектированной базе данных, где была таблица Person с отношением one2many с таблицей Code и таблицей Organization с отношением one2many с той же таблицей Code, Кодекс может применяться как к Организации, так и к Личности в зависимости от ситуации. И объект Person, и объект Organization были установлены в Cascade = All delete сирот.

То, что стало с этим перегруженным использованием таблицы кодов, состояло в том, что ни Человек, ни Организация не могли каскадировать удаление, потому что всегда была другая коллекция, в которой была ссылка на нее. Поэтому, независимо от того, как это было удалено в коде Java из любых ссылок на коллекции или объекты, удаление завершилось неудачно. Единственный способ заставить его работать - это удалить его из коллекции, которую я пытался сохранить, а затем удалить ее из таблицы Code непосредственно, а затем сохранить коллекцию. Таким образом, ссылки на него не были.

Ответ 9

Этот пост содержит блестящий трюк, чтобы определить, где каскадная проблема:
Попробуйте заменить на Cascade в то время с помощью Cascade.None(), пока вы не получите ошибку, а затем обнаружите, что каскад вызывает проблему.

Затем разрешите проблему либо путем изменения исходного каскада на что-то еще, либо с помощью ответа Tom Anderson.

Ответ 10

У меня было то же исключение, вызванное при попытке удалить ребенка из человека (Person - OneToMany - Kid). В аннотации стороны стороны:

@OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, ... cascade    = CascadeType.ALL)
public Set<Kid> getKids() {    return kids; }

В аннотации стороны Kid:

@ManyToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "person_id")
public Person getPerson() {        return person;    }

Таким образом, решение было удалить cascade = CascadeType.ALL, просто: @ManyToOne в классе Kid, и он начал работать как ожидалось.

Ответ 11

У меня была такая же проблема. Я пытался удалить и вставить в ту же транзакцию. Я добавил theEntityManager.flush(); после theEntityManager.remove(entity);.

Ответ 12

Была та же ошибка. Удаление объекта с модели сделало трюк.

Код, который показывает ошибку:

void update() {
    VBox vBox = mHboxEventSelection.getVboxSelectionRows();

    Session session = HibernateUtilEventsCreate.getSessionFactory().openSession();
    session.beginTransaction();

    HashMap<String, EventLink> existingEventLinks = new HashMap<>();
    for (EventLink eventLink : mEventProperty.getEventLinks()) {
        existingEventLinks.put(eventLink.getEvent().getName(), eventLink);
    }

    mEventProperty.setName(getName());

    for (Node node : vBox.getChildren()) {

        if (node instanceof HBox) {
            JFXComboBox<EventEntity> comboBoxEvents = (JFXComboBox<EventEntity>) ((HBox) node).getChildren().get(0);
            if (comboBoxEvents.getSelectionModel().getSelectedIndex() == -1) {
                Log.w(TAG, "update: Invalid eventEntity collection");
            }

            EventEntity eventEntity = comboBoxEvents.getSelectionModel().getSelectedItem();
            Log.v(TAG, "update(" + mCostType + "): event-id=" + eventEntity.getId() + " - " + eventEntity.getName());

            String split = ((JFXTextField) (((HBox) node).getChildren().get(1))).getText();
            if (split.isEmpty()) {
                split = "0";
            }
            if (existingEventLinks.containsKey(eventEntity.getName())) {
                // event-link did exist
                EventLink eventLink = existingEventLinks.get(eventEntity.getName());
                eventLink.setSplit(Integer.parseInt(split));
                session.update(eventLink);
                existingEventLinks.remove(eventEntity.getName(), eventLink);
            } else {
                // event-link is a new one, so create!
                EventLink link1 = new EventLink();

                link1.setProperty(mEventProperty);
                link1.setEvent(eventEntity);
                link1.setCreationTime(new Date(System.currentTimeMillis()));
                link1.setSplit(Integer.parseInt(split));

                eventEntity.getEventLinks().add(link1);
                session.saveOrUpdate(eventEntity);
            }

        }
    }

    for (Map.Entry<String, EventLink> entry : existingEventLinks.entrySet()) {
        Log.i(TAG, "update: will delete link=" + entry.getKey());
        EventLink val = entry.getValue();
        mEventProperty.getEventLinks().remove(val); // <- remove from model
        session.delete(val);
    }

    session.saveOrUpdate(mEventProperty);

    session.getTransaction().commit();
    session.close();
}

Ответ 13

Некоторые, как все вышеперечисленные решения не работали в спящем режиме 5.2.10.Final.

Но установка карты в значение null, как показано ниже:

playlist.setPlaylistadMaps(null);

Ответ 14

cascade = { CascadeType.ALL }, fetch = FetchType.LAZY