55

私は次の2つのエンティティを持っています:

1-プレイリスト:

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

この例外を修正する方法を教えてください。

4

19 に答える 19

58

解決策は、例外メッセージが示すことを正確に実行することです。

原因:org.hibernate.ObjectDeletedException:削除されたオブジェクトはカスケードによって再保存されます(削除されたオブジェクトを関連付けから削除します

削除されたオブジェクトを、それが含まれている関連付け(セット、リスト、またはマップ)から削除します。特に、からだと思いますPlayList.PlaylistadMaps。オブジェクトを削除するだけでは不十分です。オブジェクトを参照するカスケードコレクションからオブジェクトを削除する必要があります。

実際、コレクションにはが含まれているorphanRemoval = trueため、明示的に削除する必要はありません。セットから削除するだけです。

于 2012-07-25T12:40:45.767 に答える
25

FetchTypeLazyに変更すると問題が解決しました

于 2012-07-26T10:57:45.487 に答える
7

わからない場合は、どのコレクションがオブジェクトを保持しているか

私の場合、オブジェクトへのリンクを保持しているコレクションが何であるかわからなかったため、TomAndersonのソリューションを適用するのは非常に困難でした。したがって、削除されたオブジェクトへのリンクを保持しているオブジェクトを知る方法は次のとおりです。デバッガーでは、例外がスローされる前に最低の実行スタックレベルを入力する必要があります。という変数が存在する必要があるため、この変数からオブジェクトentityEntryを取得します。PersistenceContextentityEntry.persistenceContext

私にとってpersistenceContextはのインスタンスでStatefulPersistenceContextあり、この実装にはprivateフィールドparentsByChildがあり、そこから要素を含むコレクションに関する情報を取得できます。

私はEclipseデバッガーを使用していたので、このプライベートフィールドを直接取得するのは少し難しいので、使用しましたDetail Formatterデバッグ時にIDEで他のオブジェクトのプライベートフィールドを直接監視するにはどうすればよいですか?

この情報を取得した後、TomAndersonのソリューションを適用できます。

于 2016-09-04T08:42:24.157 に答える
3

この例外メッセージにも遭遇しました。私にとっては問題は異なっていました。親を削除したかった。

1つのトランザクションで:

  • まず、データベースから親を呼び出しました。
  • 次に、親のコレクションから子要素を呼び出しました。
  • 次に、子(id)の1つのフィールドを参照しました
  • 次に、親を削除しました。
  • それから私はcommitを呼び出しました。
  • 「削除されたオブジェクトは再保存されます」というエラーが発生しました。

私は2つの別々の取引をしなければならなかったことがわかりました。子供のフィールドを参照してコミットしました。次に、削除の新しいコミットを開始しました。

子要素を削除したり、親のコレクションを空にしたりする必要はありませんでした(と仮定しorphanRemoval = trueます)。実際、これは機能しませんでした。

つまり、このエラーは、子オブジェクトが削除されているときにそのオブジェクトのフィールドへの参照がある場合に表示されます。

于 2015-07-22T00:08:14.150 に答える
3

上記のすべてのソリューションが休止状態の5.2.10.Finalで機能しなかった方法。

しかし、以下のようにマップをnullに設定すると、うまくいきました。

playlist.setPlaylistadMaps(null);
于 2017-11-29T10:19:42.160 に答える
2

以下のコードを書くことでこれを解決することができました。.delete()の代わりにexecuteUpdateを使用しました

def publicSupport = caseObj?.client?.publicSupport
        if(publicSupport)
            PublicSupport.executeUpdate("delete PublicSupport c where c.id = :publicSupportId", [publicSupportId:publicSupport.id])
            //publicSupport.delete()
于 2013-04-10T07:07:00.627 に答える
1

ここで起こっているインセプションの種類。

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);
            }
        }
    }
于 2015-06-22T18:00:48.260 に答える
1

私は同じ問題を抱えていました。同じトランザクションで削除と挿入を試みていました。theEntityManager.flush();後に追加 しましたtheEntityManager.remove(entity);

于 2017-06-19T21:02:27.073 に答える
1

別の回避策

私はredochkaNikosParaskevopoulosに完全に同意します。Mahmoud Salehの答えは、状況によっては毎回ではなく、問題を解決します。私の状況では、Eagerfetchtypeが本当に必要です。それで、ストーニーが上で述べたように、私はちょうどオブジェクトをカンティアンするリストから削除しました。これが私のコードです:

Rjuエンティティ

public class Rju extends AbstractCompany implements Serializable {
    /**
     * 
     */
    private static final long serialVersionUID = 4294142403795421252L;


    //this field just duplicates @Column(name="callname") and serves for mapping to Rju fullname field
    @Column(name = "fullname")
    private String namerju;
    @NotEmpty
    @Column(name = "briefname")
    private String briefname;

    @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "otd")
    private Collection<Vstan> vStanCollection;

//  @LazyCollection(LazyCollectionOption.FALSE)
    @OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "rju", orphanRemoval = true)
    private Collection<Underrju> underRjuCollection;
.........
}

Underrjuエンティティ

public class Underrju extends AbstractCompany implements Serializable {

    /**
     * 
     */
    private static final long serialVersionUID = 2026147847398903848L;


    @Column(name = "name")
    private String name;

    @NotNull
    @Valid
    @JoinColumn(name = "id_rju", referencedColumnName = "id")
    @ManyToOne(optional = false)
    private Rju rju;
......getters and setters..........
}

と私のUnderrjuService

@Service("underrjuService")
@Transactional
public class UnderRjuServiceImpl implements UnderRjuService {

    @Autowired
    private UnderRjuDao underrjuDao;

    .............another methods........................
    @Override
    public void deleteUnderrjuById(int id) {
        Underrju underrju=underrjuDao.findById(id);
        Collection<Underrju> underrjulist=underrju.getRju().getUnderRjuCollection();
        if(underrjulist.contains(underrju)) {
            underrjulist.remove(underrju);
        }
        underrjuDao.delete(id);

    }
     .........................
}
于 2018-06-06T06:15:57.653 に答える
0

FetchTypeEAGERにする必要があるため、すべての関連付けを(null)に設定して削除し、オブジェクト(データベース内のすべての関連付けを削除)を保存してから削除します。

それは数ミリ秒を追加しますが、それらのMSを維持するためのより良い方法があれば、以下にコメントを追加してください。

それが誰かを助けることを願っています:)

于 2014-02-06T12:42:40.663 に答える
0

Personまた、不適切に設計されたデータベースでこのエラーが発生しました。このデータベースには、テーブルとの関係がone2manyCodeのテーブルOrganizationと、同じCodeテーブルとの関係がone2manyのテーブルがありました。この規範は、状況に応じて組織と個人の両方に適用される可能性があります。 PersonオブジェクトとOrganizationオブジェクトの両方がCascade=Alldeleteorphansに設定されました。

ただし、このコードテーブルの過負荷使用が発生したのは、それを参照する別のコレクションが常に存在するため、個人も組織もカスケード削除を実行できないということでした。したがって、参照しているコレクションまたはオブジェクトからJavaコードでどのように削除されても、削除は失敗します。それを機能させる唯一の方法は、保存しようとしていたコレクションから削除してから、コードテーブルから直接削除してから、コレクションを保存することでした。そのようにそれへの参照はありませんでした。

于 2015-01-02T22:10:57.980 に答える
0

この投稿には、カスケードの問題がどこにあるかを検出するための優れたトリックが含まれています。エラーが発生しなくなり、問題の原因となっているカスケードが検出されるまで、その時点でカスケード
を置き換えてみてください。Cascade.None()

次に、元のカスケードを別のものに変更するか、 Tom Andersonの回答を使用して、問題を解決します。

于 2015-10-07T17:11:10.260 に答える
0

同じ例外があり、その人から子供を削除しようとしたときに発生しました(Person-OneToMany-Kid)。人側の注釈:

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

キッド側の注釈:

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

したがって、解決策はcascade = CascadeType.ALL、単純な 削除でし@ManyToOneた。Kidクラスで、期待どおりに機能し始めました。

于 2016-10-17T20:41:50.900 に答える
0

同じエラーが発生しました。モデルからオブジェクトを削除することでうまくいきました。

間違いを示すコード:

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();
}
于 2017-10-30T12:17:14.353 に答える
0

PlaylistadMapこの問題は、の代わりにモーダルを使用して削除すると発生しますPlayList。この場合FetchType = Lazy、適切なオプションではありません。例外はスローされませんが、からのデータのみPlaylistadMapが削除され、のデータ PlayListはテーブルに残ります。それも確認してください。

于 2018-11-15T11:09:47.563 に答える
0

私はこの問題を解決するためだけに。

  1. リストの値をnullに設定しました
  2. オブジェクトを保存しました(動作しました)
  3. 新しいデータをオブジェクトに設定しました
  4. オブジェクトを再保存しました
  5. できます。!
于 2019-10-23T07:35:03.210 に答える
0

マッピングオブジェクトの関連付けを削除する必要があります。

playList.getPlaylistadMaps().setPlayList(null);
session.delete(playList);
于 2020-05-09T22:07:48.707 に答える
0

解決策は、オブジェクト間の関係を「解除」してから、削除を再試行することです。答えはあなたのログにあります:

(remove deleted object from associations): [com.xeno.advertisingsuite.web.domain.PlaylistadMap#6]

説明:何?(関連付けを削除)どこ?[id#6のPlaylistadMapオブジェクト]

于 2021-01-19T18:50:10.007 に答える
-1
cascade = { CascadeType.ALL }, fetch = FetchType.LAZY
于 2015-08-21T21:52:37.590 に答える