Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/328.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/3/wix/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 没有事务EntityManager可用的异常_Java_Spring_Spring Boot_Hibernate_Spring Data Jpa - Fatal编程技术网

Java 没有事务EntityManager可用的异常

Java 没有事务EntityManager可用的异常,java,spring,spring-boot,hibernate,spring-data-jpa,Java,Spring,Spring Boot,Hibernate,Spring Data Jpa,我面临着Spring数据JPA插入的问题。我有一个一周后运行的调度程序。它根据某些条件从源表中选择n条记录,然后检查目标表x是否存在。否则,将创建表并插入选定的数据。已成功插入目标表的数据将从源表中删除 @Component public class ArchiveService { // Some dependencies here!!! @Transactional public int archiveSmsEntries(Month month, Year ye

我面临着Spring数据JPA插入的问题。我有一个一周后运行的调度程序。它根据某些条件从源表中选择n条记录,然后检查目标表x是否存在。否则,将创建表并插入选定的数据。已成功插入目标表的数据将从源表中删除

@Component
public class ArchiveService {

    // Some dependencies here!!!

    @Transactional
    public int archiveSmsEntries(Month month, Year year) {
        // ...
        this.createNewTable(suffix);
        // ...
        // LocalDateTime start;
        // LocalDateTime end;

        int size = 200;
        boolean running = true;
        while (running) {
            Page<SmsEntry> entries = smsService.findAllForArchiving(start, end, PageRequest.of(0, size, Sort.Direction.ASC, "created"));
            result += this.saveAndDelete(entries.getContent());
            running = entries.getTotalElements() > 0;
        }

    }


    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void createNewTable(String suffix) {
        if (repo.tableExists(ArchiverUtils.table + suffix)) {
            log.warn("Archive already exists.");
        } else {
            Session session = em.unwrap(Session.class);
            session.doWork(connection -> {
                //// ...
                // Create table
                //// ...
            });
        }
    }

    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public int saveAndDelete(List<SmsEntry> entries) {

        if (entries.isEmpty())
            return 0;

        AtomicInteger r = new AtomicInteger(0);
        try {
            Session session = em.unwrap(Session.class);
            session.doWork(connection -> {
                boolean autoCommit = connection.getAutoCommit();
                connection.setAutoCommit(true);
                PreparedStatement ps = connection.prepareStatement("INSERT STATEMENT");

                for (SmsEntry entry : entries) {
                    ps.setInt(1, entry.getId());
                    ps.setDouble(2, entry.getCost());

                    ps.addBatch();
                }

                r.set(Arrays.stream(ps.executeBatch()).sum());
                if (r.get() > 0) {
                    entryService.deleteAllById(entries.stream().map(SmsEntry::getId).collect(Collectors.toList()));
                }

                ps.close();
                connection.setAutoCommit(autoCommit);
            });
        } catch (Exception e) {
            log.error(e.getMessage(), e);
        }
        return r.get();
    }

}

所以我真的不知道为什么会抛出这个,以及如何解决它。我在网上看到类似的问题,比如和。我的主要任务是获取200条记录,并立即进行操作和保存(立即提交给DB)。
如果有任何帮助,我将不胜感激。谢谢。

有一些你没有考虑过的,春天的代理。与您的情况一样,最有可能的是CGlib执行对象代理,因为您没有基于接口声明服务。您使用的是事务性方法,但只有当事务性方法是公共的并且调用在类的“外部”进行时,它才会是Transactionall。为什么?由于spring代理您的类,它调用您的方法,但如果您在事务性方法中有方法调用,spring也无法知道该方法是否也是真正的事务性方法。在另一个类中写入CREATETABLE方法,然后再试一次。

有一些你没有考虑过的东西,Spring代理。与您的情况一样,最有可能的是CGlib执行对象代理,因为您没有基于接口声明服务。您使用的是事务性方法,但只有当事务性方法是公共的并且调用在类的“外部”进行时,它才会是Transactionall。为什么?由于spring代理您的类,它调用您的方法,但如果您在事务性方法中有方法调用,spring也无法知道该方法是否也是真正的事务性方法。在另一个类中编写createtable方法,然后重试。感谢您的回复。我刚刚实现了你上面提到的。我将saveAndDelete()和createNewTable()方法提取到一个新组件中。我将运行一个测试,如果我愿意分享结果。谢谢。嗨@Guardian,我想告诉你它成功了。谢谢
org.springframework.dao.InvalidDataAccessApiUsageException: No transactional EntityManager available; nested exception is java.lang.IllegalStateException: No transactional EntityManager available
    at org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:371)
    at org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:257)
    at org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:528)
    at org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)
    at org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)
    at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.proceed(CglibAopProxy.java:749)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:691)
...