2012-04-19 20 views
35

Mam skonfigurowane i uruchomione dane źródłowe i hibernacja. Mogę zapisywać rekordy za pomocą danych sprężynowych, ale z jakiegoś powodu nie jestem w stanie uruchomić zapytania, które zaktualizuje wszystkie pola logiczne w tabeli.aktualizowanie wartości boolowskiej w danych źródłowych jpa przy użyciu @Query z hibernacją

Próbowałem to:

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

Próbowałem też tak:

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

Parametry podział i rozdział nadchodzą prawdziwe, ale nie ma zmiany na stole.

p.s. Używam również bazy danych mysql.

Odpowiedz

108

Używam 3.1 i wiosna Wiosna WZP danych. Miałem podobny problem. Podczas próby aktualizacji wielu rekordów w jednym zapytaniu ciągle pojawiał się błąd.

Tak, miałem coś takiego.

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

Błąd:

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

Tak, po googlowania na chwilę, I okazało się, że trzeba było dodać @Modifying.

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

Ale potem był otrzymuję następujący błąd:

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

Więc pomyślałem, mój problem był już problem transakcji i poszedłem z powrotem do Google, aby go badania i okazało się, że trzeba dodaj @Transactional teraz. Wygląda na to, że @Modifying wymaga również @Transactional.

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

ale potem mam następujący błąd:

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

Znowu googled na chwilę i doszedł do wniosku, że moja konfiguracja była źle i to okazało się prawdą. Brakowało niektórych konfiguracji 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"/> 

To była długa podróż, ale w końcu udało mi się. Mam nadzieję, że to pomoże komuś, starając się "zapłacić dalej", jak wielu innych pomogło mi w ich wspaniałych blogach, odpowiedziach i komentarzach.

+2

​​nie powinna być konieczna, ponieważ Spring Data automatycznie stosuje transakcje oparte na adnotacjach do interfejsów repozytorium. –

+1

również upewnij się, że adnotacja jest importowana z org.springframework.transaction.annotation nie javax – barryku

+0

Używam dokładnie tej samej konfiguracji z następującą klasą z repozytorium Spring JPA, ale otrzymuję błąd podczas tworzenia komponentu bean. (Nie jest to konkretny błąd, po prostu mówi, że nie można utworzyć repozytorium). Dlaczego miałoby to być? '@Repository interfejs IContactRepository rozciąga PagingAndSortingRepository { \t @Modifying \t @query ("DELETE FROM kontakt C = gdzie c.circle.id: circleId") \t void deleteAllMembersOf (@param ("circleId") Long circleId); } ' – noego

8

Aby wykonać zapytań modyfikujących trzeba opisywać metody z dodatkowym @Modifying jak przedstawiono w reference documentation tak:

@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

Więc ... Czy to praca dla ciebie, czy nie? Jestem trochę zdziwiony, co mówisz;) –

+1

Przepraszam oliver, byłem trochę zmęczony i zrobiłem literówkę. Nie, to nie pomogło.Postaraj się zrozumieć, że ta opcja "@Modyfikowanie" jest przydatna, jeśli twoje repozytorium jest opatrzone komentarzem tylko do odczytu. W ten sposób możesz mieć I repozytorium, które jest głównie tylko do odczytu, ale nadal pozwala ci mieć w nim metody zapisu. – aki

+0

To nie ma nic wspólnego z 'readOnly' - przynajmniej nie bezpośrednio. 'readOnly' dotyczy transakcji,' @ Modifying' odnosi się do wywołania w 'EntityManager'. Oczywiście nie ma sensu próba wykonania metody modyfikującej w transakcji typu "tylko do odczytu". –

3

Dla mnie to działało z następujących adnotacji:

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

dla mnie też, że pracował z następujących adnotacji:

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