org.hibernate.AssertionFailure: Немагчыма выканаць ня-выдаліць, напрыклад,

Я атрымліваю гэтую памылку сцвярджэння спячага рэжыму, калі я спрабую зрабіць чытанне пасля некаторых аперацый выдалення.

Я не мог знайсці нічога пра гэта «Не ўдаецца выканаць ня-выдаленне» памылка, акрамя Soure кода , таму я думаю, што, можа быць, я раблю нешта настолькі відавочна, няправільна ...

Трасіроўкі стэка ніжэй,

AssertionFailure:43 -  - HHH000099: an assertion failure occured (this may indicate a bug in         Hibernate, but is more likely due to unsafe use of the session): org.hibernate.AssertionFailure: Unable     to perform un-delete for instance X
org.hibernate.AssertionFailure: Unable to perform un-delete for instance X
   at org.hibernate.engine.spi.ActionQueue.unScheduleDeletion(ActionQueue.java:508)
   at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:157)
   at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870)
   at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863)
   at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346)
   at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
   at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
   at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
   at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
   at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
   at org.hibernate.event.internal.DefaultPersistEventListener.justCascade(DefaultPersistEventListener.java:190)
   at org.hibernate.event.internal.DefaultPersistEventListener.entityIsDeleted(DefaultPersistEventListener.java:229)
   at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:158)
   at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870)
   at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863)
   at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346)
   at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
   at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
   at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
   at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
   at org.hibernate.event.internal.AbstractSaveEventListener.cascadeBeforeSave(AbstractSaveEventListener.java:423)
   at org.hibernate.event.internal.DefaultPersistEventListener.justCascade(DefaultPersistEventListener.java:190)
   at org.hibernate.event.internal.DefaultPersistEventListener.entityIsPersistent(DefaultPersistEventListener.java:183)
   at org.hibernate.event.internal.DefaultPersistEventListener.onPersist(DefaultPersistEventListener.java:147)
   at org.hibernate.internal.SessionImpl.firePersistOnFlush(SessionImpl.java:870)
   at org.hibernate.internal.SessionImpl.persistOnFlush(SessionImpl.java:863)
   at org.hibernate.engine.spi.CascadingAction$8.cascade(CascadingAction.java:346)
   at org.hibernate.engine.internal.Cascade.cascadeToOne(Cascade.java:380)
   at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:323)
   at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
   at org.hibernate.engine.internal.Cascade.cascadeCollectionElements(Cascade.java:409)
   at org.hibernate.engine.internal.Cascade.cascadeCollection(Cascade.java:350)
   at org.hibernate.engine.internal.Cascade.cascadeAssociation(Cascade.java:326)
   at org.hibernate.engine.internal.Cascade.cascadeProperty(Cascade.java:208)
   at org.hibernate.engine.internal.Cascade.cascade(Cascade.java:165)
   at org.hibernate.event.internal.AbstractFlushingEventListener.cascadeOnFlush(AbstractFlushingEventListener.java:160)
   at org.hibernate.event.internal.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:151)
   at org.hibernate.event.internal.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:88)
   at org.hibernate.event.internal.DefaultAutoFlushEventListener.onAutoFlush(DefaultAutoFlushEventListener.java:58)
   at org.hibernate.internal.SessionImpl.autoFlushIfRequired(SessionImpl.java:1186)
   at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1241)
   at org.hibernate.internal.QueryImpl.list(QueryImpl.java:101)
   at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:257)
   at org.hibernate.ejb.criteria.CriteriaQueryCompiler$3.getResultList(CriteriaQueryCompiler.java:254)

З павагай,

3

10 адказы

У мяне была такая ж праблема. Тое, што адбылося, што я выдаленне звязаных бабоў, давайце назавем іх А і Б. Я выдаліў Bs, а затым прыступіў знайсці Entities C, якія спасылаюцца As, і даў бобу тыпу A ў якасці параметру для запыту і зрабіць запыт выклікаў гэта выключэнне , Маё меркаваньне, што каскад анатацыю на прадпрыемства D, які спасылаецца А і В, было выдаленае, як калі я выдаліў Bs, а затым даць аб'ект, які ўжо быў выдалены на ўзроўні БД ў якасці параметру для запыту прычынай праблемы.

Перагрупоўка код так, што я спачатку выдаліць спасылкі з С у А і затым прайсці выдаліць абодва B і А, здаецца, працуе вакол гэтага.

2
дададзена
Гэта дапамагло мне. Гэта «асаблівасць» Hibernate вызначана можа выкарыстоўваць некаторыя лепш дакументацыю.
дададзена аўтар user1071914, крыніца

I know this is really late answer but this might help someone, sometime in future!! This answer is about similar error (if someone lands on this question, luckily): AssertionFailure - HHH000099: an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)

Я атрымліваю гэтую памылку, таму што я спрабаваў захаваць клавішы сеанс з суб'ектам, ані-NULL атрыбуты першасны ключ быў усталяваны ў становішчы <�кода > нулявым .

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "calc_id", unique = true, nullable = false)
private Long calcId;

тут GenerationType.IDENTITY не працаваў і не усталёўваючы значэнне першаснага ключа перад Захаваць . І Tadaa .... Я атрымаў тую ж памылку, як я ўжо казаў. Таму я проста замяніў код з ніжэйпададзенымі.

@SequenceGenerator(name="identifier", sequenceName="mytable_id_seq", allocationSize=1)  
@GeneratedValua(strategy=GenerationType.SEQUENCE, generator="identifier")
1
дададзена

Гэта для ўсіх, хто прыязджае сюды праз пошукі не можа не-выдаленне сцвярджэння (як я).

У мяне была тая ж праблема з зацвярджэннем у некаторым кодзе Падрадчык пакінуў нас, але для мяне гэта праблема не была каскадны, што працаваў выдатна.

Па нейкай прычыне Hibernate загружаў той жа аб'ект двойчы ў адной і той жа сесіі. Я знайшоў толькі гэта, калі капаў глыбока ў вантробы Hibernate.

Я выкарыстаў org.hibernate.stat.SessionStatistics, якія вы можаце атрымаць ад сесіі і PersistenceContext, якія вы атрымаеце ад SessionImpl

Session session = (Session)this.entityManager.unwrap(Session.class);
persistenceContext = ((SessionImpl)session).getPersistenceContext();

каб даведацца, што загружаны Hibernate.

Калі я раздрукаваў поўны спіс асобаў, з

public  void printSessionInfo(String where,HashSet printClasses){
        Log log = Logging.getLog(PersistentSesionInfo.class);
        Session session = (Session)this.entityManager.unwrap(Session.class);

        SessionStatistics stats = session.getStatistics();
        HashMap entityMap = new HashMap();
        if(stats!=null){
            log.info("EntityManager #0 has #1 managed entities and #2 collections at #3", getHash(entityManager),stats.getEntityCount(),stats.getCollectionCount(),where);
            List entities = com.google.common.collect.Lists.newArrayList(stats.getEntityKeys());
            Iterator iter = entities.iterator();
            while(iter.hasNext()){
                EntityKey ek = iter.next();
                if(entityMap.containsKey(ek.getEntityName())){
                    entityMap.get(ek.getEntityName()).increase();
                }else{
                    entityMap.put(ek.getEntityName(), new Counter());
                }
                if(printClasses!=null && printClasses.contains(ek.getEntityName())){
                    try{
                    Object o = ((HibernateSessionProxy)session).get(ek.getEntityName(), ek.getIdentifier());
                    if(o!=null){
                        log.info("Entity #0 of type #1  id=#2 System hash=#3 object hash #4", o,Hibernate.getClass(o).getSimpleName(),ek.getIdentifier(),Integer.toHexString(System.identityHashCode(o)),Integer.toHexString(o.hashCode()));
                    }
                    }catch(javax.persistence.EntityNotFoundException e ){
                        log.error("Entity #0 with id #1 cannot be found anymore", ek.getEntityName(),ek.getIdentifier());
                    }
                }
            }
            for(Entry entry : entityMap.entrySet()){
                log.info("Entity #0 count #1", entry.getKey(),entry.getValue());
            }

        }
    }
public class Counter {
        int count = 1;

        public void increase(){
            count++;
        }

        public int getCount(){
            return count;
        }

        public String toString(){
            return String.valueOf(count);
        }
    }

Мае Суб'екты былі пералічаныя там, але калі я

persistenceContext.getEntry(myEntity)

ён вяртаецца нуль (entityManager.contains (MyEntity) вярнуўся праўда)!

Я ітэрацыя па ўсім EntityKeys ад persistenceContext.getEntitiesByKey() (магчыма, спатрэбіцца, каб скапіяваць спіс перад ітэрацыі над ім)

List list = new ArrayList();
list.addAll(persistenceContext.getEntitiesByKey().keySet());

У там EntityKey для MyEntity быў там, але ён паказваў на іншы асобнік (разные System.identiyHashCode).

Я павінен выказаць здагадку, што праблема ў канчатковым рахунку, была з роўнымі і метадамі Hashcode у сутнасці (як гэта часта бывае з праблемамі сутнасцяў). Я заўважыў, што падобныя асобнікі сутнасцяў будуць мець той жа хэш-код, нават калі іх бацька адрозніваўся.

Я выкарыстаў «павінны ўзяць на сябе», як праблема не пайшла адразу (не перазагружаць сервер, як я выкарыстоўваю liverebel). Толькі пасля перазагрузкі сервера з падтрымкай TRACE на Hibernate была праблема знікла. Пасля адкату ўсіх іншых змяненняў адладкі і толькі пакідаючы РОЎНА/метады Hashcode ён усё яшчэ працуе.

Таму, калі ў вас ёсць дзіўныя невытлумачальныя праблемы з суб'ектамі - праверыць роўныя і метады Hashcode! І выкарыстоўваць Hibernate класы PersistenceContext і SessionStatistics для яго адладкі.

1
дададзена

Я таксама сутыкнуўся з гэтай жа трасіроўку стэка сёння, выкарыстоўваючы Hibernate 4.x ў якасці пастаўшчыка 2.x JPA. Вось што я даведаўся пра тое, што мне трэба змяніць, каб выправіць гэта паднятае выключэнне.

У маёй JPA адлюстроўваецца мадэль прадметнай вобласці, у мяне ёсць глыбокі графік, заснаваны OneToMany А мае мноства Bs, У маюць шмат Cs, C мае мноства Ds, D мае шмат Es. Каскаднага тыпу на ўсе адзін да manys СОВСЕМ. Назад паказваючы ManyToOne існуе на кожным ўзровень і код, які мы напісалі працаваў добра, калі гэтыя ManyToOne адносіны былі дэфолт (г.зн. ахвотна загружаны)

У выкарыстанні крыўдзячы выпадку я дыягнаставаных сёння мы чытаем дыскрэтны набор Ds з запытам JPQL, і, як мы перабіраем гэта мноства, мы называем EntityManager.remove (с), дзе мы атрымліваем асобнік гр, папрасіўшы асобнік D для яго бацька/ўладальнік C асобніка.

Калі экзэмпляр з атрымліваецца ў D, каб адносіны C быць лянівым загружаны, выклік EntityManager.remove (с) не скардзіцца, але наступны выклік EntityManager.flush() прыводзіць да тэмы выключэнняў.

Загаловак Выключэнне не падымаецца, калі на працягу гэтага JPQL запыту, адносіны ад D да З нецярпеннем загружаецца шляхам дадання «Join выбаркі d.c с».

Так, проста думаў, што я хацеў бы падзяліць гэтыя вынікі ў выпадку, калі хто-то сутыкаецца з гэтым пытаннем і вышэй дае ім уяўленне аб тым, што яны могуць змяніць, каб прымусіць замаўчаць праблему.

1
дададзена

выдаліць метады і хэш-код роўны ад вашага асобы. ён працаваў для мяне

1
дададзена
Гэта не гучыць як добрае рашэнне.
дададзена аўтар Magnilex, крыніца

Я <�моцны> каскад = CascadeType.ALL і ён працаваў, прадставіць, што вы атрымліваеце яго сутнасць У, якімі абазначаюцца ад аб'екта A. Калі ласка, пастаўце каскад усё на А,

Таксама залежыць, хто трымае сувязь у маім выпадку суадносіны было нанесена на карту А.

0
дададзена

У мяне была такая ж памылка. Я меў класы A і B. У мае спіс As і А мае зваротную спасылку B. А мае таксама спасылку на аб'ект C (Cascade.All), які выклікае выключэнне на аднавіць сцёртыя.

Я паспрабаваў перамясціць аб'ект А да іншага аб'екту В.

Гэта выклікае выключэнне:

objectOfA.getObjectOfB().getListOfAs().remove(objectOfA);
objectOfB1.getListOfAs().add(objectOfA);
objectOfA.seObjectOfB(objectOfB1);

dao.flush()

Гэта быў працоўны раствор.

objectOfA.seObjectOfB(objectOfB1);

dao.flush()

bjectOfA.getObjectOfB().getListOfAs().remove(objectOfA);
objectOfB1.getListOfAs().add(objectOfA);

Апошнія два радкі не заўсёды з'яўляецца абавязковым, паколькі спячы рэжым выпраўляе гэта пасля перазагрузкі.

Я не ўпэўнены, калі яго памылкі ў спячым рэжыме. Выключэнне occoured таму, што спячы рэжым параўноўвае аб'ект C з проксі-серверам таго ж C з «==» у ActionQueue.unScheduleDeletion ()

0
дададзена

Мае два цэнта, для тых, хто прыбывае на гэтую тэму і з дапамогай Grails.

У выпадку мі, праблема ўзнікла ад змены дамена ўстойлівага ўласцівасці ў скоропреходящий (прадастаўленні канкрэтнай ўстаноўкі і атрымання), і які мае канструктар, выкарыстоўваючы версію карты і перадаючы зменную там.

Арыгінальны клас дамена было так:

class MyDomain {
    String content
}

І я ствараў асобнік, як:

def domain = new MyDomain( content: "sample content" )

Абнаўленне дамена:

class MyDomain {
    static transients = [ 'content' ]

    byte[] compressed

    String getContent() {
        compressed ? uncompress( compressed ) : null
    }

    void setContent( String content ) {
        compressed = content ? compress( content ) : null 
    }
}

Канструктар не будзе скардзіцца, але setContent не называецца, і як ні дзіўна, замест таго, каб даць памылку праверкі або памылку SQL, то ўзнікае памылка, згаданыя ў гэтай тэме.

Рашэнне простае:

def domain = new MyDomain()
domain.content = "sample content"

Такім чынам, злучны выклікаецца.

0
дададзена

it might be a bug of hibernate, If you read (load() a proxy instance) and then call delete and save on it . https://hibernate.atlassian.net/browse/HHH-8374

0
дададзена

Я таксама пакутаваў ад гэтай праблемы раз. У выпадку выкарыстання двунакіраванага адлюстравання, калі мы выкарыстоўваем некалькі @OneToMany і выкарыстоўваць <�моцны> mappedby annotatin, а затым сервер шоу такога роду памылкі. Такім чынам, вы можаце лёгка вырашыць гэтую праблему з дапамогай

@JoinTable(name="c",[email protected](name="c_id"),[email protected](name="l_id"))

замест таго, каб выкарыстоўваць mappedby ..

0
дададзена