Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/spring/14.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 如何将Spring事务管理与Hibernate集成?_Java_Spring_Hibernate_Spring Transactions - Fatal编程技术网

Java 如何将Spring事务管理与Hibernate集成?

Java 如何将Spring事务管理与Hibernate集成?,java,spring,hibernate,spring-transactions,Java,Spring,Hibernate,Spring Transactions,我一直在尝试使用HibernateTransactionManager来管理服务层中的事务,但它不起作用。 用于创建PlatformTransactionManager的Java类配置: @Configuration @EnableTransactionManagement @PropertySource("classpath:hibernateConfig.properties") public class HibernateConfig { @Value(&qu

我一直在尝试使用HibernateTransactionManager来管理服务层中的事务,但它不起作用。 用于创建PlatformTransactionManager的Java类配置:

@Configuration
@EnableTransactionManagement
@PropertySource("classpath:hibernateConfig.properties")
public class HibernateConfig {

    @Value("${hibernate.dialect}")
    private String dialect;

    //Other hibernate properties 

    @Autowired
    private DataSource dataSource;

    private Properties hibernateProperties() {
        Properties hibernateProperties = new Properties();

        hibernateProperties.put("hibernate.dialect", dialect);
        //Other hibernate properties removed here for brevity 

        return hibernateProperties;
    }

    @Bean
    @DependsOn("dataSource")
    public SessionFactory sessionFactory() throws IOException {
        LocalSessionFactoryBean  sessionFactoryBean =
                new LocalSessionFactoryBean();

        sessionFactoryBean.setDataSource(dataSource);
        sessionFactoryBean.setPackagesToScan("com.ldp.vigilantBean.domain");
        sessionFactoryBean.setHibernateProperties(hibernateProperties());
        sessionFactoryBean.afterPropertiesSet();

        return sessionFactoryBean.getObject();
    }

    @Bean
    @DependsOn("sessionFactory")
    public PlatformTransactionManager platformTransactionManager() throws IOException {
        HibernateTransactionManager txManager = new HibernateTransactionManager();
        txManager.setSessionFactory(sessionFactory());
        txManager.afterPropertiesSet();

        return txManager;
    }
}
在这个方法调用的后面,有两个对持久层的调用,最后抛出一个运行时异常。因此,我希望回滚对存储库的这两个调用

@Override
    @Transactional(rollbackFor = { RuntimeException.class })
    public boolean removeCartItem(Long cartItemId) {

        Cart cart = getCartOutOfContext();

        Optional<CartItem> optCartItemToRemove =
                cart.getCartItems()
                    .stream()
                    .filter(cartItem -> cartItem.getCartItemId().equals(cartItemId))
                    .findAny();

        if (optCartItemToRemove.isPresent()) {

            CartItem cartItemToRemove = optCartItemToRemove.get();

            //There is a bug with PersistentSet in Hibernate that makes
            //using .contains() and .remove() methods of Set interface unpredictable.
            //This is a workaround: reset the whole set.
            cart.setCartItems(
                cart.getCartItems().stream()
                                   .filter(cartItem -> !cartItem.equals(cartItemToRemove))
                                   .collect(Collectors.toSet())
            );

            Optional<Product> optProduct =
                    productRetrievalRepository.getProductById(cartItemToRemove.getProduct().getProductId());
            if (!optProduct.isPresent())
                throw new IllegalArgumentException("Specified product not found");
            Product productToRemove = optProduct.get();
            productToRemove.setUnitsInOrder(productToRemove.getUnitsInOrder() - cartItemToRemove.getQuantity());
            //First call
            productAlterRepository.updateProduct(productToRemove);

            //Second call
            cartRepository.updateCart(cart);
            if (true) throw new RuntimeException("An exception to check transactions");

            return true;
        } else
            return false;

    }
如果我是对的,当只使用一个资源(在我的例子中是Hibernate存储库)时,您不需要像Atomikos这样的全局事务提供程序。 我认为应该有3个事务:一个外部事务(服务调用)和两个内部事务(到存储库)。其思想是,如果其中一个内部事务失败,它将导致外部事务回滚,这意味着对存储库的所有两个调用都将回滚。

在updateProduct(产品)内部,除了服务级别的声明性事务外,您还再次打开了编程事务。因此,它将忽略Spring容器管理的事务管理器,并单独使用自己的事务管理器。
@Override
    @Transactional(rollbackFor = { RuntimeException.class })
    public boolean removeCartItem(Long cartItemId) {

        Cart cart = getCartOutOfContext();

        Optional<CartItem> optCartItemToRemove =
                cart.getCartItems()
                    .stream()
                    .filter(cartItem -> cartItem.getCartItemId().equals(cartItemId))
                    .findAny();

        if (optCartItemToRemove.isPresent()) {

            CartItem cartItemToRemove = optCartItemToRemove.get();

            //There is a bug with PersistentSet in Hibernate that makes
            //using .contains() and .remove() methods of Set interface unpredictable.
            //This is a workaround: reset the whole set.
            cart.setCartItems(
                cart.getCartItems().stream()
                                   .filter(cartItem -> !cartItem.equals(cartItemToRemove))
                                   .collect(Collectors.toSet())
            );

            Optional<Product> optProduct =
                    productRetrievalRepository.getProductById(cartItemToRemove.getProduct().getProductId());
            if (!optProduct.isPresent())
                throw new IllegalArgumentException("Specified product not found");
            Product productToRemove = optProduct.get();
            productToRemove.setUnitsInOrder(productToRemove.getUnitsInOrder() - cartItemToRemove.getQuantity());
            //First call
            productAlterRepository.updateProduct(productToRemove);

            //Second call
            cartRepository.updateCart(cart);
            if (true) throw new RuntimeException("An exception to check transactions");

            return true;
        } else
            return false;

    }

请删除该选项,然后重试。

无效。我认为应该有3个事务:一个外部事务(服务调用)和两个内部事务(到存储库)。其思想是,如果其中一个内部事务失败,它将导致外部事务回滚,这意味着对存储库的所有两个调用都将回滚。@服务实现中的事务性就足够了,建议这样做。请删除所有编程事务管理内容(开始/提交/回滚)。在repository/dao级别,只保留与DB处理相关的代码。一旦您的行会话.getTransaction().commit();被执行了,它不能倒转好了,它成功了。我不知道为什么我不认为语法管理的事务在这里是一个障碍。非常感谢您的时间和努力。
*** LOG4J *** HHH000490: Using JtaPlatform implementation: [org.hibernate.engine.transaction.jta.platform.internal.NoJtaPlatform]