2012-04-19 10 views
35

I dati di primavera e di sospensione sono configurati e in esecuzione. Posso salvare i record utilizzando i dati di primavera, ma per qualche motivo non sono in grado di eseguire query che aggiornerà tutti i campi booleani in una tabella.aggiornamento del valore booleano in primavera dati jpa utilizzando @Query, con ibernazione

ho provato questo:

@Query("update Content v set v.published = false where v.division = :division and v.section = :section") 
void unPublishContent(@Param("division") String division, 
         @Param("section") String section); 

Ho provato anche questo:

@Query("update Content v set v.published = 0 where v.division = :division and v.section = :section") 
void unPublishContent(@Param("division") String division, 
         @Param("section") String section); 

Parametri divisione e la sezione si stanno avverando, ma nessun cambiamento sul tavolo.

p.s. Sto anche usando il database mysql.

risposta

108

sto usando Primavera 3.1 e Spring JPA dati. Stavo avendo un problema simile. Ho riscontrato costantemente un errore durante il tentativo di aggiornare più record in 1 query.

Quindi, ho avuto qualcosa di simile.

@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2") 
public void updateAllUsers(long state, long serverid); 

Errore:

org.hibernate.hql.QueryExecutionRequestException: Not supported for DML operations 

Così, dopo googling per un po ', ho scoperto che si doveva aggiungere @Modifying.

@Modifying 
@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2") 
public void updateAllUsers(long state, long serverid); 

Ma poi mi è stato sempre il seguente errore:

...  
nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: Executing an update/delete query; 
nested exception is javax.persistence.TransactionRequiredException: Executing an update/delete query 
... 

Così, ho pensato che il mio problema era ormai un problema di transazione e sono tornato a google per la ricerca e scoperto che si deve aggiungi @Transactional adesso. Sembra che @Modifying richieda anche @Transactional.

@Modifying 
@Transactional 
@Query("UPDATE User u SET u.state = ?1 WHERE u.server.id = ?2") 
public void updateAllUsers(long state, long serverid); 

ma poi ho ottenuto il seguente errore:

No value for key [org.apache.commons.dbcp.BasicDataSource (...) ] bound to thread 

Ancora una volta ho cercato su google per un po 'ed è giunto alla conclusione che la mia configurazione era sbagliato e si è rivelato essere vero. Mi mancavano alcuni configs xml.

<beans:bean class="org.springframework.orm.jpa.JpaTransactionManager" id="transactionManager"> 
    <beans:property name="entityManagerFactory" ref="entityManagerFactory"/> 
</beans:bean> 

<tx:annotation-driven transaction-manager="transactionManager"/> 

E 'stato un lungo viaggio ma alla fine ho funzionato. Spero che questo possa aiutare qualcuno, cercando di "ripagarlo" come molti altri mi hanno aiutato con i loro meravigliosi blog, risposte e commenti.

+2

non dovrebbe essere necessario in quanto Spring Data applica automaticamente transazioni basate su annotazioni alle interfacce del repository. –

+1

assicurati inoltre che l'annotazione sia importata da org.springframework.transaction.annotation non javax – barryku

+0

Sto utilizzando la stessa configurazione con la seguente classe con il repository JPA di Spring, ma ricevo un errore durante la creazione di bean. (Non è un errore specifico, dice solo che il repository non può essere creato). Perché dovrebbe essere? '@Repository interfaccia IContactRepository estende PagingAndSortingRepository { \t @Modifying \t @query ("cancellare dal contatto c dove c.circle.id =: circleId") \t vuoto deleteAllMembersOf (@param ("circleId") Long circleId); } ' – noego

8

per eseguire query modifica è necessario annotare il metodo con un ulteriore @Modifying come indicato nel reference documentation come questo:

@Modifying 
@Query("update Content v set v.published = false where v.division = :division and v.section = :section") 
void unPublishContent(@Param("division") String division, 
        @Param("section") String section); 
+0

Quindi ... ha fatto il lavoro per voi o no? Sono un po 'perplesso di quello che stai dicendo;) –

+1

scusa Oliver, ero un po' stanco e ho fatto un refuso. No, non ha aiutato.Formare quello che capisco è che questa opzione "@Modifying" è utile se il tuo repository è annotato con sola lettura. In questo modo puoi avere un repository che è principalmente di sola lettura ma che ti consente comunque di avere metodi di scrittura al suo interno. – aki

+0

Questo non ha niente a che vedere con 'readOnly' - almeno non direttamente. 'readOnly' riguarda le transazioni,' @ Modifica 'riguarda una chiamata su' EntityManager'. Ovviamente non ha senso cercare di eseguire un metodo di modifica in una transazione di sola lettura. –

3

Per me ha funzionato con i seguenti annotazioni:

@Modifying 
@Query("update JsonContactImport x set x.isImported = true where x.id in :ids") 
@Transactional 
void updateImported(@Param("ids") List<Long> ids); 
7

anche per me, ha funzionato con i seguenti annotazioni:

@Modifying 
@Query("update User u set u.active=1 where a.id=?1") 
@Transactional 
void activeUser(Long id);