java - 批量保存 JPA 实体 - TransactionRequiredException

标签 java spring-boot jpa entitymanager

我有以下类来使用实体管理器批量保存实体:

@Repository
@Transactional
public class AbstractRepositoryAdapter
{
    private static final Logger logger  = LoggerFactory.getLogger(AbstractRepositoryAdapter.class);
    @PersistenceContext
    private EntityManager entityManager;

    @Transactional
    public <O extends GenericEntity> void save(List<O> entities){
        entities.forEach(entity->{
            entityManager.persist(entity);          
        }); 
        System.out.println("saved from save(List<O> entities)");
    }
    @Transactional
    public  <O extends GenericEntity> void write(List<O> entities)
    {
        if (!CollectionUtils.isEmpty(entities))
        {
            List<List<O>> listOfList = CollectionHelper.split(entities, 1000);

            ExecutorService executorService = Executors.newFixedThreadPool(10);
            List<Future<?>> futures = new ArrayList<Future<?>>();

            for (List<O> subEntities : listOfList)
            {
                Future<?> future = executorService.submit(new BatchExecutor<O>(entityManager, subEntities));
                futures.add(future);
            }

            ObjectHelper.wait(futures.toArray(new Future<?>[0]));// wait until all tasks are finished

            executorService.shutdown();
        }
    }
    @Transactional
    private static class BatchExecutor<O extends GenericEntity> implements Runnable
    {
        private EntityManager em    = null;
        private List<O>         entities    = null;


        public BatchExecutor(EntityManager em, List<O> entities)
        {
            this.em=em;
            this.entities = entities;
        }

        @Override
        @Transactional
        public void run()
        {
            String sql = "";
            try 
            {
                entities.forEach(entity->{
                    em.persist(entity);
                });

            }
            catch (Exception e)
            {
                logger.debug("Unable to save the entities for -> {} ", sql);
            }

        }
    }
}

如果我尝试使用 write 方法来保存我的实体列表,则会出现以下异常:

javax.persistence.TransactionRequiredException: No transactional EntityManager available

但是如果我使用save方法来保存我的实体列表,它可以正常工作并且实体将保存到数据库

但是批量保存实体的代码有什么问题。事务属性也存在于此。理想情况下它应该有效。

注意:GenericEntity 是我所有实体类实现的接口(interface)。

我想编写一种多线程方式来保存通用的实体。但不知何故它不起作用。如果我迭代原始列表并尝试保存它,那么它就可以工作。

最佳答案

您的 BatchExecutor 实例不是由 Spring 创建的,因此该方法上的 @Transactional 注释不起作用。

关于java - 批量保存 JPA 实体 - TransactionRequiredException,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52042647/

相关文章:

spring - 如何将 Spring Boot 与带有嵌入式 Tomcat 的 JSF 2.2 集成

hibernate - setParameter() 没有设置正确的引号

java - 如何在单表继承(JPA)中使用@UniqueConstraint?

java - android Horizo​​ntalScrollView 中左右滚动的按钮

java - org.jivesoftware :smack:jar:3. 4.1-0cec571 的 POM 丢失

java - 无法使用通过 Hikari 访问的 H2 数据库登录

java - 在@Service中创建ObjectMapper的@Bean时出错

java - JPA如何使复合外键成为复合主键的一部分

java - 将 JSON 反序列化为类实例

Java:在主函数中创建新的自定义对象?