logo

Решение ошибки: DML операция delete не поддерживается в JpaRepository

Быстрый ответ

Для успешного выполнения DML-операции удаления с помощью JpaRepository, необходимо применить аннотации @Modifying и @Transactional следующим образом:

Java
Скопировать код
@Modifying
@Transactional
@Query("DELETE FROM EntityName e WHERE e.attribute = ?1")
void performDeletion(String value);

Аннотация @Modifying информирует Spring приложение о намерении выполнить операции обновления или удаления, в то время как @Transactional контролирует транзакцию, обеспечивая сохранение внесённых изменений в базе данных.

Понимание ключевых принципов и подходов к проектированию в Spring Data JPA играет решающую роль в успешной реализации пользовательских DML-операций, включая delete. Аннотация @Modifying указывает на изменение данных при выполнении определённого запроса, отличая его от запросов на выборку. Типом возвращаемого значения таких методов как правило является void или int/Integer, где числовое значение показывает количество затронутых записей.

Для правильного составления запросов на удаление сущностей по определённым условиям, примените в вашем интерфейсе JpaRepository комбинацию аннотаций @Modifying, @Query и @Transactional. Параметры запроса задавайте с использованием @Param, чтобы чётко связать их с плейсхолдерами в запросе.

Избегаем семантики транзакций

Рекомендуется применять @Transactional, аннотируя методы сервиса, а не интерфейсы репозитория. Это обеспечивает сохранение целостности транзакции на уровне слоя сервисов и предоставляет четкую декомпозицию ответственности в приложении. Вот пример такого применения:

Java
Скопировать код
public interface MyService {
    void deleteSomeData(String value);
}

@Service
public class MyServiceImpl implements MyService {
    
    private final MyRepository myRepository;

    @Autowired
    public MyServiceImpl(MyRepository myRepository) {
        this.myRepository = myRepository;
    }

    @Override
    @Transactional
    public void deleteSomeData(String value) {
        myRepository.performDeletion(value);
    }
}

EntityManager против JpaRepository: нерешённые вопросы

Для более сложных DML-операций EntityManager обладает большим функционалом, чем JpaRepository. При выполнении сложной операции delete предпочтительнее использовать entityManager.createQuery().executeUpdate(), который дает возможность для детальной настройки транзакции и выполнения запроса.

Ошибки, заслуживающие внимания

  • Не забудьте, что использование @Transactional рекомендовано только для классов сервисов, не для интерфейсов репозитория.
  • Будьте внимательны при импорте аннотаций @Modifying, @Transactional и @Query.
  • Понимайте принципы распределения транзакций. Операции внутри методов с аннотацией @Transactional должны рассматриваться как единый блок логической работы.

Визуализация

Допустим, вы пользуетесь измельчителем древесины для уничтожения больших веток.

Markdown
Скопировать код
Попытка выполнить DML с помощью JpaRepository:
Java
Скопировать код
jpaRepository.delete(entity); // JpaRepository не справится с этим сам

Для DML-операций типа delete потребуются специализированные инструменты:

Java
Скопировать код
@Modifying
@Query("DELETE FROM Entity e WHERE e.id = :id")
void performDeletion(@Param("id") Long id); // Эффективное удаление специализированным запросом

Продолжая аналогию, метод будет работать подобно точечному лучу Человека-Муравья, разработанному специально для выполнения DML-задач в Spring Data JPA.

Динамические условия, динамические ответы

Для динамического определения условий удаления сущностей, Criteria API или Querydsl предлагают продвинутые возможности создания SQL-запросов, что особенно полезно при формировании фильтров на основе переменных критериев.

Готовность к распространённым ошибкам

Важно уделить внимание таким традиционным ошибкам, как:

  • Неверное использование индексации JPQL-запросов вроде ?1, ?2 и т.д.
  • Пропуск аннотации @Param при использовании в параметрах методов, что ведёт к неполадкам с привязкой параметров.
  • Недооценка обязательности использования @Modifying при операциях обновления или удаления, что вызывает ошибки, связанные с неподдерживаемыми операциями.

Полезные материалы

  1. Spring Data JPA :: Spring Data JPAофициальная документация по использованию @Modifying в Spring Data JPA.
  2. java – Spring – No EntityManager with actual transaction available for current thread – cannot reliably process 'persist' call – Stack Overflow — обзор типичных проблем связанных с @Modifying и @Transactional и способы их решения.
  3. Transactional (Spring Framework 6.1.3 API)официальный JavaDoc для @Transactional, содержащий детальное описание практического использования.
  4. Guide to @Modifying in Spring Data JPA — пошаговое описание использования аннотации @Modifying в Spring Data JPA.
  5. Spring Data JPA Transactions and Isolation Tutorial — объяснение настроек транзакций и уровней изоляции в Spring Data JPA.
  6. Advanced Spring Data JPA – Specifications and Querydsl — глубокое погружение в Specifications и Querydsl для создания сложных запросов в Spring Data JPA.
  7. 39 The Java Persistence Query Language (Release 7) — всестороннее руководство по языку JPQL, широко применяемому в пользовательских методах репозитория в Spring Data JPA.