Sospensione: l'aggiornamento in batch ha restituito un conteggio di righe imprevisto dall'aggiornamento: 0 conteggio effettivo delle righe: 0 previsto: 1


141

Ottengo il seguente errore di ibernazione. Sono in grado di identificare la funzione che causa il problema. Sfortunatamente ci sono diverse chiamate DB nella funzione. Non riesco a trovare la riga che causa il problema poiché l'ibernazione scarica la sessione alla fine della transazione. L'errore di ibernazione di seguito indicato sembra un errore generale. Non ha nemmeno menzionato quale Bean causi il problema. Qualcuno ha familiarità con questo errore di ibernazione?

org.hibernate.StaleStateException: Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1
        at org.hibernate.jdbc.BatchingBatcher.checkRowCount(BatchingBatcher.java:93)
        at org.hibernate.jdbc.BatchingBatcher.checkRowCounts(BatchingBatcher.java:79)
        at org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:58)
        at org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:195)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:235)
        at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:142)
        at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
        at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
        at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
        at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
        at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
        at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:584)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransacti
onManager.java:500)
        at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManag
er.java:473)
        at org.springframework.transaction.interceptor.TransactionAspectSupport.doCommitTransactionAfterReturning(Transaction
AspectSupport.java:267)
        at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:106)
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:170)
        at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:176)

Grazie @Peter Mortensen. Ho aggiornato la mia email.
Sujee,

Ho lo stesso problema. Questo non è un grosso problema poiché accade molto raramente. L'uso di show_sql non è pratico poiché la riproduzione di questo comportamento richiede milioni di transazioni. Tuttavia, poiché ciò accade ripetutamente durante un test di sistema che eseguo (che contiene milioni di transazioni) sospetto che ci sia un motivo specifico.
daniel_or_else,

Ho incontrato questo problema mentre ho cercato di aggiornare righe aventi NO modifiche. Non aggiornare qualcosa se non c'è differenza.
fifman,

Risposte:


62

Senza codice e mappature per le tue transazioni, sarà quasi impossibile indagare sul problema.

Tuttavia, per ottenere una migliore gestione delle cause del problema, provare quanto segue:

  • Nella tua configurazione di ibernazione, imposta hibernate.show_sql su true. Questo dovrebbe mostrare l'SQL che viene eseguito e causa il problema.
  • Impostare i livelli di registro per Spring e Hibernate su DEBUG, ancora una volta questo ti darà un'idea migliore su quale linea causa il problema.
  • Creare un unit test che replica il problema senza configurare un gestore delle transazioni in primavera. Questo dovrebbe darti un'idea migliore della linea di codice offensiva.

Spero che aiuti.


21
hibernate.show_sql> preferirei consigliare di impostare la categoria di registro org.hibernate.SQL su DEBUG. In questo modo non è necessario modificare la configurazione dell'ibernazione solo per la registrazione.
Thierry,

L'uso di "show_sql" può essere molto dettagliato e non praticabile in produzione. Per questo ho modificato la clausola catch nella riga 74 della classe BatchingBatcher per stampare l'istruzione con ps.toString () in modo da avere solo l'istruzione che presenta il problema.
Orden,

71

Ho ottenuto la stessa eccezione durante l'eliminazione di un record per ID che non esiste affatto. Quindi controlla che il record che stai aggiornando / eliminando esista effettivamente nel DB


12
Ho avuto questo problema quando ho rimosso un figlio da una relazione genitore-figlio, salvato il genitore (che elimina il figlio) e quindi ho provato a eliminare manualmente il figlio.
Dave Thieben,

Questo ha risolto il mio problema. Il record non esisteva e il mio servizio chiamava il metodo updateAll () mentre in realtà doveva chiamare il metodo createOrUpdateAll (). Grazie.
Mital Pritmani,

3
quindi come risolvere il problema? Se ottengo un record e quindi lo elimino; ma se il sistema lo elimina già prima di eliminarlo, un altro, la mia applicazione genererà l'eccezione.
Pietroso

@davethieben, questa era esattamente l'informazione di cui avevo bisogno. Non mi rendevo conto che la relazione genitore-figlio persisteva nelle eliminazioni.
snowe,

La soluzione è utilizzare select per l'aggiornamento quando si recupera il record per bloccare la riga, quindi nient'altro può eliminarlo prima di farlo.
Matthew Leggi

55

Soluzione: nel file di mapping Hibernate per la proprietà id, se si utilizza una classe di generatori, per quella proprietà non è necessario impostare esplicitamente il valore utilizzando un metodo setter.

Se si imposta esplicitamente il valore della proprietà Id, verrà generato l'errore sopra riportato. Controlla questo per evitare questo errore. oppure Errore mostra quando si menziona nel file di mappatura il campo generator = "native" o "incremental" e nel DATABASE la tabella mappata non è auto_incrementata Soluzione: vai al DATABASE e aggiorna la tabella per impostare auto_increment


2
Assolutamente giusto. Questa deve essere la risposta giusta. Grazie @ Rēda Biramanē
Kuldeep Verma,

1
Tuttavia , PUOI impostare il valore ID su "0", quindi Hibernate si sentirà libero di sovrascriverlo
forresthopkinsa,

1
Grazie! Non sono sicuro del perché questa non sia la risposta con il punteggio più alto.
Stuart McIntyre,

18

Questo mi è successo una volta per caso quando stavo assegnando ID specifici ad alcuni oggetti (test) e poi stavo cercando di salvarli nel database. Il problema era che nel database esisteva una politica specifica per l'impostazione degli ID degli oggetti. Basta non assegnare un ID se si dispone di una politica a livello di ibernazione.


15

Nel mio caso, sono arrivato a questa eccezione in due casi simili:

  • In un metodo annotato con @Transactionalho avuto una chiamata a un altro servizio (con tempi di risposta lunghi). Il metodo aggiorna alcune proprietà dell'entità (dopo il metodo, l'entità esiste ancora nel database). Se l'utente richiede due volte il metodo (poiché ritiene che non funzioni la prima volta) quando esce dal metodo transazionale la seconda volta, Hibernate tenta di aggiornare un'entità che ha già cambiato il suo stato dall'inizio della transazione. Mentre Hibernate cerca un'entità in uno stato e trova la stessa entità ma è già stata modificata dalla prima richiesta, genera un'eccezione in quanto non può aggiornare l'entità. È come un conflitto in GIT.
  • Ho ricevuto richieste automatiche (per il monitoraggio della piattaforma) che aggiornano un'entità (e il rollback manuale pochi secondi dopo). Ma questa piattaforma è già utilizzata da un team di test. Quando un tester esegue un test nella stessa entità delle richieste automatiche (entro lo stesso centesimo di millisecondo), ottengo l'eccezione. Come nel caso precedente, quando si esce dalla seconda transazione, l'entità precedentemente recuperata è già cambiata.

Conclusione: nel mio caso, non è stato riscontrato un problema nel codice. Questa eccezione viene generata quando Hibernate rileva che l'entità recuperata per la prima volta dal database è cambiata durante la transazione corrente , quindi non può scaricarla nel database poiché Hibernate non sa quale sia la versione corretta dell'entità: quella corrente recupero delle transazioni all'inizio; o quello già memorizzato nel database.

Soluzione: per risolvere il problema, dovrai giocare con Hibernate LockMode per trovare quello più adatto alle tue esigenze.


Ciao, grazie per la tua utile risposta. Potresti informarti, per quale LockMode sei andato alla fine, per eliminare l'errore. Sto affrontando un problema simile, quando un'API viene colpita in successione in diversi millisecondi, a causa di un clic dell'utente inavvertitamente due volte. Il blocco pessimistico danneggia le prestazioni; quindi sarà interessato a sapere cosa alla fine hai scelto?
Madhur Bhaiya,

1
Era da molto tempo che non avevo il problema e non ricordo bene la soluzione esatta che ho messo in atto, ma era LockMode.READo LockMode.OPTIMISTIC.
Sergio Lema,

13

Ho appena riscontrato questo problema e ho scoperto che stavo cancellando un record e cercando di aggiornarlo in seguito in una transazione Hibernate.


9

Ciò può accadere quando i trigger eseguono query DML aggiuntive (modifica dei dati) che influiscono sul conteggio delle righe. La mia soluzione era aggiungere quanto segue all'inizio del mio trigger:

SET NOCOUNT ON;

1
Questa risposta mi ha inviato nella giusta direzione. Stavo lavorando con un database legacy che aveva un trigger - fortunatamente stavo sostituendo ciò che il trigger ha fatto con il codice, quindi ho potuto semplicemente cancellarlo.
S. Baggy,

2
+1 Anche questo era il mio problema. Stavo usando postgresql, quindi avevo bisogno di usare l'annotazione @SQLInsert per disattivare il controllo del conteggio delle righe: technology-ebay.de/the-teams/mobile-de/blog/…
s1mm0t

SET NOCOUNT OFF *
G. Ciardino

7

Stavo affrontando lo stesso problema. Il codice funzionava nell'ambiente di test. Ma non funzionava in un ambiente di stadiazione.

org.hibernate.jdbc.BatchedTooManyRowsAffectedException: Batch update returned unexpected row count from update [0]; actual row count: 3; expected: 1

Il problema era che la tabella aveva una singola voce per ogni chiave primaria nel test della tabella DB. Ma nel DB di gestione temporanea c'erano più voci per la stessa chiave primaria. (Il problema è nella gestione temporanea del DB, la tabella non ha avuto vincoli di chiave primaria e inoltre c'era una voce multipla.)

Quindi ogni volta che si esegue l'operazione di aggiornamento viene fallito. Cerca di aggiornare un singolo record e prevede di ottenere il conteggio degli aggiornamenti come 1. Ma poiché nella tabella c'erano 3 record per la stessa chiave primaria, il conteggio degli aggiornamenti dei risultati trova 3. Poiché il conteggio degli aggiornamenti previsti e il conteggio degli aggiornamenti dei risultati effettivi non corrispondono , Genera eccezione e ripristina.

Dopo aver rimosso tutti i record che hanno una chiave primaria duplicata e aggiunto vincoli di chiave primaria. Funziona benissimo.

Hibernate - Batch update returned unexpected row count from update: 0 actual row count: 0 expected: 1

il conteggio delle righe effettive: 0 // indica che non è stato trovato alcun record per l'aggiornamento
dell'aggiornamento: 0 // indica che non è stato trovato alcun record, pertanto non è
previsto alcun aggiornamento : 1 // indica che è previsto almeno 1 record con la chiave nella tabella db.

Qui il problema è che la query sta cercando di aggiornare un record per una chiave, ma l'ibernazione non ha trovato alcun record con la chiave.


Ciao @ParagFlume, ho ricevuto lo stesso errore "L'aggiornamento in batch ha restituito un conteggio di righe imprevisto dall'aggiornamento: 0 numero di righe effettive: 0 previsto: 1" quando provo a selezionare un oggetto dal mio database il problema esiste solo in qualsiasi produzione, hai qualche idea su come risolvere questo problema, mi trovo in una situazione critica. Saluti !
James,

Penso che la query non abbia trovato alcun record in db, si aspetta di trovare un record in db, che sta cercando di aggiornare. puoi controllare manualmente / query-browser se il record esiste effettivamente su db.
ParagFlume,

sì, il record esiste, ma il mio problema è il motivo per cui l'ibernazione tenta di aggiornare, sto solo usando un servizio selezionato per ottenere l'oggetto dal database!
James,

potrebbe essere che stai cercando di cambiare lo stato degli oggetti. e la sessione è ancora aperta.
ParagFlume,

come posso controllare questo comportamento, perché non sono la persona che sviluppa il servizio ...
James,

5

Come dice Giulio , ciò accade quando si verifica un aggiornamento su un oggetto che ha i suoi figli eliminati. (Probabilmente perché c'era bisogno di un aggiornamento per l'intero oggetto padre e talvolta preferiamo eliminare i bambini e reinserirli sul padre (nuovi, vecchi non contano) insieme a qualsiasi altro aggiornamento che il padre potrebbe avere su uno dei i suoi altri campi semplici) Quindi ... affinché questo funzioni, elimina i bambini (all'interno di una Transazione) chiamando childrenList.clear()(Non scorrere tra i bambini ed elimina ognuno con alcuni childDAO.delete(childrenList.get(i).delete()))e impostando @OneToMany(cascade = CascadeType.XXX ,orphanRemoval=true)dalla parte dell'oggetto padre. Quindi aggiornare il padre (fatherDAO.update (padre)). (Ripeti per ogni oggetto padre) Il risultato è che i bambini hanno il loro legame con il padre rimosso e quindi vengono rimossi come orfani dalla struttura.


5

Ho riscontrato questo problema in cui abbiamo avuto molti rapporti.

Nel file di mapping hbm hibernate per master, per oggetto con disposizione tipo impostata, aggiunto cascade="save-update"e ha funzionato bene.

Senza questo, per impostazione predefinita l'ibernazione tenta di aggiornare per un record inesistente e in tal modo inserisce invece.


4

Può succedere anche quando provi a UPDATEun CHIAVE PRIMARIA .


3

ho riscontrato lo stesso problema e ho verificato che ciò può verificarsi a causa della chiave primaria di incremento automatico. Per risolvere questo problema, non inserire il valore di incremento automatico con il set di dati. Inserisci i dati senza la chiave primaria.


3

Un altro modo per ottenere questo errore è se si dispone di un elemento null in una raccolta.


2

succede quando si tenta di eliminare lo stesso oggetto e quindi aggiornare nuovamente lo stesso oggetto, utilizzare questo dopo l'eliminazione

Session.clear ();


2

Questo è successo anche a me, perché avevo il mio ID come Long, e stavo ricevendo dalla vista il valore 0, e quando ho provato a salvare nel database ho ricevuto questo errore, quindi l'ho corretto impostando l'id su null.


1

Mi sono imbattuto in questo problema quando stavo iniziando manualmente e commettendo transazioni all'interno del metodo annotato come @Transactional. Ho risolto il problema rilevando se esisteva già una transazione attiva.

//Detect underlying transaction
if (session.getTransaction() != null && session.getTransaction().isActive()) {
    myTransaction = session.getTransaction();
    preExistingTransaction = true;
} else {
    myTransaction = session.beginTransaction();
}

Quindi ho permesso a Spring di gestire il commit della transazione.

private void finishTransaction() {
    if (!preExistingTransaction) {
        try {
            tx.commit();
        } catch (HibernateException he) {
            if (tx != null) {
                tx.rollback();
            }
            log.error(he);
        } finally {
            if (newSessionOpened) {
                SessionFactoryUtils.closeSession(session);
                newSessionOpened = false;
                maxResults = 0;
            }
        }
    }
}

1

Questo succede quando hai dichiarato JSF Managed Bean come

@RequestScoped;

quando dovresti dichiarare come

@SessionScoped;

Saluti;


1

Ho ricevuto questo errore quando ho provato ad aggiornare un oggetto con un ID che non esisteva nel database. Il motivo del mio errore era che avevo assegnato manualmente una proprietà con il nome "id" alla rappresentazione JSON dell'oggetto sul lato client e quindi, quando si deserializzava l'oggetto sul lato server, questa proprietà "id" sovrascriveva la variabile di istanza ( chiamato anche "id") che Hibernate avrebbe dovuto generare. Quindi fai attenzione a nominare le collisioni se stai usando Hibernate per generare identificatori.


1

Ho anche incontrato la stessa sfida. Nel mio caso stavo aggiornando un oggetto che non esisteva nemmeno, usando hibernateTemplate.

In realtà nella mia applicazione stavo ottenendo un oggetto DB da aggiornare. E mentre aggiornavo i suoi valori, ho anche aggiornato il suo ID per errore, e sono andato avanti per aggiornarlo e mi sono imbattuto in detto errore.

Sto usando hibernateTemplateper le operazioni CRUD.


1

Dopo aver letto tutte le risposte, non ho trovato nessuno con cui parlare dell'attributo inverso dell'ibernazione.

Secondo me dovresti anche verificare nella tua relazione mappando se la parola chiave inversa è opportunamente settata. La parola chiave inversa viene creata per definire da quale parte è il proprietario per mantenere la relazione. La procedura per l'aggiornamento e l'inserimento varia in base a questo attributo.

Supponiamo di avere due tabelle:

principal_table , middle_table

con una relazione da uno a molti . Le classi di mapping hiberntate sono rispettivamente Principal e Middle .

Quindi la classe Principal ha un SET di oggetti Middle . Il file di mapping xml dovrebbe essere simile al seguente:

<hibernate-mapping>
    <class name="path.to.class.Principal" table="principal_table" ...>
    ...
    <set name="middleObjects" table="middle_table" inverse="true" fetch="select">
        <key>
            <column name="PRINCIPAL_ID" not-null="true" />
        </key>
        <one-to-many class="path.to.class.Middel" />
    </set>
    ...

Poiché l'inverso è impostato su "vero", significa che la classe "media" è il proprietario della relazione, quindi la classe principale NON AGGIORNA la relazione.

Quindi la procedura per l'aggiornamento potrebbe essere implementata in questo modo:

session.beginTransaction();

Principal principal = new Principal();
principal.setSomething("1");
principal.setSomethingElse("2");


Middle middleObject = new Middle();
middleObject.setSomething("1");

middleObject.setPrincipal(principal);
principal.getMiddleObjects().add(middleObject);

session.saveOrUpdate(principal);
session.saveOrUpdate(middleObject); // NOTICE: you will need to save it manually

session.getTransaction().commit();

Questo ha funzionato per me, ma puoi suggerire alcune edizioni per migliorare la soluzione. In questo modo impareremo tutti.


1

Nel nostro caso abbiamo finalmente scoperto la causa principale di StaleStateException.

In effetti stavamo eliminando la riga due volte in una singola sessione di ibernazione. Prima usavamo ojdbc6 lib, e questo andava bene in questa versione.

Ma quando siamo passati a odjc7 o ojdbc8, l'eliminazione dei record due volte ha generato un'eccezione. C'era un bug nel nostro codice in cui stavamo eliminando due volte, ma ciò non era evidente in ojdbc6.

Siamo riusciti a riprodurre con questo codice:

Detail detail = getDetail(Long.valueOf(1396451));
session.delete(detail);
session.flush();
session.delete(detail);
session.flush();

Al primo scaricamento l'ibernazione va e apporta modifiche al database. Durante il 2 ° flush l'ibernazione confronta l'oggetto della sessione con il record della tabella effettiva, ma non è stato possibile trovarne uno, quindi l'eccezione.


1

Questo problema si verifica principalmente quando stiamo cercando di salvare o aggiornare l'oggetto che è già stato recuperato in memoria da una sessione in esecuzione. Se hai recuperato l'oggetto dalla sessione e stai provando ad aggiornare nel database, questa eccezione potrebbe essere generata.

Ho usato session.evict (); per rimuovere prima la cache archiviata in ibernazione o se non si desidera correre il rischio di perdere dati, meglio creare un altro oggetto per archiviare la temperatura dei dati.

     try
    {
        if(!session.isOpen())
        {
            session=EmployeyDao.getSessionFactory().openSession();
        }
            tx=session.beginTransaction();

        session.evict(e);
        session.saveOrUpdate(e);
        tx.commit();;
        EmployeyDao.shutDown(session);
    }
    catch(HibernateException exc)
    {
        exc.printStackTrace();
        tx.rollback();
    }

1

Emissione Hibernate 5.4.1 e HHH-12878

Prima di Hibernate 5.4.1, le eccezioni di errore di blocco ottimistico (ad es. StaleStateExceptionO OptimisticLockException) non includevano la dichiarazione di errore.

Il problema HHH-12878 è stato creato per migliorare l'ibernazione in modo che quando si genera un'eccezione di blocco ottimistico, PreparedStatementviene registrata anche l' implementazione JDBC :

if ( expectedRowCount > rowCount ) {
    throw new StaleStateException(
            "Batch update returned unexpected row count from update ["
                    + batchPosition + "]; actual row count: " + rowCount
                    + "; expected: " + expectedRowCount + "; statement executed: "
                    + statement
    );
}

Tempo di test

Ho creato il BatchingOptimisticLockingTestrepository GitHub Java Persistence ad alte prestazioni per dimostrare come funziona il nuovo comportamento.

Innanzitutto, definiremo Postun'entità che definisce una @Versionproprietà, abilitando quindi il meccanismo di blocco ottimistico implicito :

@Entity(name = "Post")
@Table(name = "post")
public class Post {

    @Id
    @GeneratedValue(strategy = GenerationType.SEQUENCE)
    private Long id;

    private String title;

    @Version
    private short version;

    public Long getId() {
        return id;
    }

    public Post setId(Long id) {
        this.id = id;
        return this;
    }

    public String getTitle() {
        return title;
    }

    public Post setTitle(String title) {
        this.title = title;
        return this;
    }

    public short getVersion() {
        return version;
    }
}

Abiliteremo il batch JDBC utilizzando le seguenti 3 proprietà di configurazione:

properties.put("hibernate.jdbc.batch_size", "5");
properties.put("hibernate.order_inserts", "true");
properties.put("hibernate.order_updates", "true");

Creeremo 3 Postentità:

doInJPA(entityManager -> {
    for (int i = 1; i <= 3; i++) {
        entityManager.persist(
            new Post()
                .setTitle(String.format("Post no. %d", i))
        );
    }
});

E Hibernate eseguirà un inserimento batch JDBC:

SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')
SELECT nextval ('hibernate_sequence')

Query: [
    INSERT INTO post (title, version, id) 
    VALUES (?, ?, ?)
], 
Params:[
    (Post no. 1, 0, 1), 
    (Post no. 2, 0, 2), 
    (Post no. 3, 0, 3)
]

Quindi, sappiamo che il batching JDBC funziona perfettamente.

Ora, repliciamo il problema del blocco ottimistico:

doInJPA(entityManager -> {
    List<Post> posts = entityManager.createQuery("""
        select p 
        from Post p
        """, Post.class)
    .getResultList();

    posts.forEach(
        post -> post.setTitle(
            post.getTitle() + " - 2nd edition"
        )
    );

    executeSync(
        () -> doInJPA(_entityManager -> {
            Post post = _entityManager.createQuery("""
                select p 
                from Post p
                order by p.id
                """, Post.class)
            .setMaxResults(1)
            .getSingleResult();

            post.setTitle(post.getTitle() + " - corrected");
        })
    );
});

La prima transazione seleziona tutte le Postentità e modifica le titleproprietà.

Tuttavia, prima che il primo EntityManagervenga scaricato, eseguiremo una seconda transizione usando il executeSyncmetodo.

La seconda transazione modifica la prima Post, quindi versionverrà incrementata:

Query:[
    UPDATE 
        post 
    SET 
        title = ?, 
        version = ? 
    WHERE 
        id = ? AND 
        version = ?
], 
Params:[
    ('Post no. 1 - corrected', 1, 1, 0)
]

Ora, quando la prima transazione tenta di svuotare il EntityManager, otterremo il OptimisticLockException:

Query:[
    UPDATE 
        post 
    SET 
        title = ?, 
        version = ? 
    WHERE 
        id = ? AND 
        version = ?
], 
Params:[
    ('Post no. 1 - 2nd edition', 1, 1, 0), 
    ('Post no. 2 - 2nd edition', 1, 2, 0), 
    ('Post no. 3 - 2nd edition', 1, 3, 0)
]

o.h.e.j.b.i.AbstractBatchImpl - HHH000010: On release of batch it still contained JDBC statements

o.h.e.j.b.i.BatchingBatch - HHH000315: Exception executing batch [
    org.hibernate.StaleStateException: 
    Batch update returned unexpected row count from update [0]; 
    actual row count: 0; 
    expected: 1; 
    statement executed: 
        PgPreparedStatement [
            update post set title='Post no. 3 - 2nd edition', version=1 where id=3 and version=0
        ]
], 
SQL: update post set title=?, version=? where id=? and version=?

Pertanto, è necessario eseguire l'aggiornamento a Hibernate 5.4.1 o versioni successive per beneficiare di questo miglioramento.


0

Ciò si è verificato se si modifica qualcosa nel set di dati utilizzando la query sql nativa ma l'oggetto persistente per lo stesso set di dati è presente nella cache della sessione. Usa session.evict (yourObject);



0

Uno dei casi

SessionFactory sf=new Configuration().configure().buildSessionFactory();
Session session=sf.openSession();

UserDetails user=new UserDetails();

session.beginTransaction();
user.setUserName("update user agian");
user.setUserId(12);
session.saveOrUpdate(user);
session.getTransaction().commit();
System.out.println("user::"+user.getUserName());

sf.close();

0

Stavo affrontando questa eccezione e l'ibernazione funzionava bene. Ho provato a inserire manualmente un record usando pgAdmin, qui il problema è diventato chiaro. La query di inserimento SQL restituisce 0 inserimento. e c'è una funzione trigger che causa questo problema perché restituisce null. quindi devo solo impostarlo per tornare nuovo. e finalmente ho risolto il problema.

spero che aiuti qualsiasi corpo.


0

Ho ricevuto questo errore perché ho erroneamente mappato la IDcolonna usandoId(x => x.Id, "id").GeneratedBy.**Assigned**();

Problema risolto utilizzando Id(x => x.Id, "id").GeneratedBy.**Identity**();


0

Questo mi succede perché mi manca la dichiarazione ID nella classe bean.


0

Nel mio caso si è verificato un problema con il database poiché uno degli Stored Procs consumava tutta la CPU causando tempi di risposta del DB elevati. Una volta ucciso questo problema è stato risolto.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.