2013-11-02 2 views
11

У меня есть объект User и объект Role. Отношения определяются следующим образом:Spring Data JPA удалить исходное исключение запросов на запросы

@OneToMany 
@JoinTable(name="USER_ROLES", [email protected](name="ROLE_ID")) 
private List<Role> roles = null; 

Теперь, когда я удалить роль, мне нужно удалить роль из всех пользователей, которые имеют эту роль. Обычно вы делаете что-то вроде этого, просматривая всех пользователей с этой ролью, удаляя роль из списка и сохраняя пользователя. Однако, когда может быть более миллиона пользователей, я не хочу перебирать это множество объектов в приложении. Итак, я хочу использовать собственный запрос для удаления строк из таблицы соединения USER_ROLES. Я попробовал, добавив это в моем хранилище:

@Query(value="DELETE FROM user_roles WHERE role_id = ?1", nativeQuery=true) 
public void deleteRoleFromUsersWithRole(Long roleId); 

Однако, когда я делаю это, я вижу следующее в журналах:

[EL Fine]: sql: 2013-11-02 14:27:14.418--ClientSession(707349235)--Connection(2096606500)--Thread(Thread[http-bio-8080-exec-4,5,main])--DELETE FROM user_roles WHERE role_id = ? 
    bind => [1000110139999999953] 
[EL Fine]: sql: 2013-11-02 14:27:14.478--ClientSession(707349235)--Thread(Thread[http-bio-8080-exec-4,5,main])--SELECT 1 
[EL Warning]: 2013-11-02 14:27:14.482--UnitOfWork(1795045370)--Thread(Thread[http-bio-8080-exec-4,5,main])--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.DatabaseException 
Internal Exception: org.postgresql.util.PSQLException: No results were returned by the query. 
Error Code: 0 
Call: DELETE FROM user_roles WHERE role_id = ? 
    bind => [1000110139999999953] 
Query: DataReadQuery(sql="DELETE FROM user_roles WHERE role_id = ?") 

Я не понимаю, что No results were returned by the query. говорит. Запись удаляется из базы данных, но это исключение заставляет все взорваться.

Может кто-нибудь, пожалуйста, скажите мне, что я здесь делаю неправильно?

ответ

26

Метод, аннотированный с помощью @Query, выполняет запрос для чтения из базы данных. Не обновлять базу данных. Чтобы сделать это, так как the documentation указано, что вам нужно добавить @Modifying аннотацию к методу:

Все вышеперечисленные разделы описывают, как объявить запросы для доступа к данному объекту или коллекции объектов. Разумеется, вы можете добавить настраиваемое поведение для изменения, используя средства, описанные в разделе 1.3 «Пользовательские реализации хранилищ Spring Data». Поскольку этот подход является выполнимым для всеобъемлющих пользовательских функциональных возможностей, вы можете добиться выполнения модифицирующих запросов, которые фактически требуют привязки параметров, аннотируя метод запроса с помощью @Modification:

Пример 2.13. Объявление манипулируя запросов

@Modifying 
@Query("update User u set u.firstname = ?1 where u.lastname = ?2") 
int setFixedFirstnameFor(String firstname, String lastname); 

Это вызовет запрос аннотированный методу, обновляя запрос вместо выбора одного.

+4

А, я все еще довольно новичок в Spring Data и JPA. Думаю, мне нужно больше времени проводить в документах. Я должен отметить, что мне также пришлось добавить аннотацию '@ Transactional', чтобы заставить ее работать. Спасибо за вашу помощь. – dnc253