在 Spring Boot 应用程序中,JPA 标准删除连续下降并出现奇怪的异常

Posted

技术标签:

【中文标题】在 Spring Boot 应用程序中,JPA 标准删除连续下降并出现奇怪的异常【英文标题】:JPA criteria delete continuously fall with strange exception, in Spring boot application 【发布时间】:2016-12-15 09:51:59 【问题描述】:

我有一个 jpa 实体,它是某种 http 请求日志,我想创建一个计划任务,其中也删除旧条目,在应用程序启动时删除旧条目。

我可以一个一个地删除,但是当我想批量删除旧的时,我总是会遇到同样的异常(见下文)

我用一种方法void cleanLog();创建了一个自定义存储库

    public class RequestLogRepositoryImpl implements RequestLogRepositoryCustom 

    private final LogWrapper log = new LogWrapper(this.getClass());

    @Autowired
    @Qualifier(value = "someQualifier")
    private LocalContainerEntityManagerFactoryBean emf;

    @Autowired
    private CleanUpProperties cleanUpProperties;

    private EntityManager em;
    private CriteriaBuilder cb;

    @PostConstruct
    private void postBusinessEventRepositoryCustomImpl() 
        this.em = emf.getNativeEntityManagerFactory().createEntityManager();
        this.cb = em.getCriteriaBuilder();
    

    @Override
    public void cleanLog() 
        Calendar calendar = Calendar.getInstance();
        calendar.add(cleanUpProperties.getField().getValue(), -(cleanUpProperties.getLength()));

        log.info("Delete before :" + calendar.getTime());

        CriteriaDelete<RequestLogEntity> delete = cb.createCriteriaDelete(RequestLogEntity.class);
        Root<RequestLogEntity> root = delete.from(RequestLogEntity.class);

        delete.where(cb.lessThanOrEqualTo(root.get("requestTime"), calendar.getTime()));

        em.createQuery(delete).executeUpdate();
    

它正确地创建了删除查询,但是当尝试执行它时总是会出现相同的异常,无论是在启动时,还是计划任务或直接想通过应用程序管理界面运行它。

org.springframework.dao.InvalidDataAccessApiUsageException:正在执行 更新/删除查询;嵌套异常是 javax.persistence.TransactionRequiredException:执行一个 更新/删除查询 org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:413) ~[spring-orm-4.2.7.RELEASE.jar:4.2.7.RELEASE] 在 org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:227) ~[spring-orm-4.2.7.RELEASE.jar:4.2.7.RELEASE]

在我调用此存储库方法的服务中,使用@Transactional 进行注释,这意味着这应该在事务中。根据我的资源,我还应该使用@Modifying 注释和@Transactional,但也没有使用它。

这是我的服务方法的样子,这是我捕获异常的地方

@Override
@Modifying
@Transactional
public boolean clearLog() 
    try
        requestLogRepository.cleanLog();
    catch (Exception e)
        log.fatal("Error:", e);
        return false;
    
    return true;

【问题讨论】:

【参考方案1】:

您正在创建自己的 EntityManager 实例,不知道 Spring 事务处理。

只需注入实体管理器:

@PersistenceContext
private EntityManager em;

【讨论】:

@PersistenceContext(unitName="someQualifier") 在这种情况下,应用程序使用更多的数据源,并且让工厂是我从遗留代码中学到的不好的做法。有趣的是它在许多其他地方都能正常工作。

以上是关于在 Spring Boot 应用程序中,JPA 标准删除连续下降并出现奇怪的异常的主要内容,如果未能解决你的问题,请参考以下文章

Spring Data JPA在Spring Boot中的应用

使用 Spring Data JPA 在 Spring Boot 2 应用程序中发布数据

在 Spring Boot MVC 应用程序中在 JPA 和 Mongo 之间切换

在 Spring Boot 应用程序上添加 jpa 依赖项时,Okta Spring Boot 不起作用

如何在 Spring Boot 中从应用程序属性文件中读取 jpa 命名查询?

在 Spring Boot 应用程序中,JPA 标准删除连续下降并出现奇怪的异常