事务注释在带有 EntitManager 的纯 Spring 中不起作用

问题描述 投票:0回答:1

我有一个简单的 bookdao 类:

package com.spring;

import jakarta.persistence.EntityManager;
import jakarta.persistence.TypedQuery;
import jakarta.persistence.criteria.CriteriaBuilder;
import jakarta.persistence.criteria.CriteriaQuery;
import jakarta.persistence.criteria.Root;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;
import org.springframework.transaction.annotation.Transactional;

import java.util.List;



@Repository
public class BookDao {
    @Autowired
    private EntityManager entityManager;

    @Transactional
    public void create(Book book) {
//        entityManager.getTransaction().begin();
        entityManager.persist(book);
//        entityManager.getTransaction().commit();
    }

    public List<Book> findAll() {

        CriteriaBuilder cb = entityManager.getCriteriaBuilder();
        CriteriaQuery<Book> cq = cb.createQuery(Book.class);

        Root<Book> root = cq.from(Book.class);
        cq.select(root);

        TypedQuery<Book> query = entityManager.createQuery(cq);
        return query.getResultList();

    }
}

我有一个主要方法,我尝试将一本新书保存到数据库中:

package com.spring;

import org.springframework.context.ApplicationContext;
import org.springframework.context.annotation.AnnotationConfigApplicationContext;

public class Main {
    public static void main(String[] args) {
        ApplicationContext context = new AnnotationConfigApplicationContext(SpringConfig.class);

        BookDao bookDao = context.getBean(BookDao.class);

        Book book = new Book("Sample Book");

        bookDao.create(book);
        System.out.println("xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" + bookDao.findAll());
    }
}

最后是我的 spring 配置:


package com.spring;

import jakarta.persistence.EntityManager;
import jakarta.persistence.EntityManagerFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.jdbc.datasource.DriverManagerDataSource;
import org.springframework.orm.jpa.JpaTransactionManager;
import org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.annotation.EnableTransactionManagement;

import javax.sql.DataSource;

@Configuration
@EnableTransactionManagement
public class SpringConfig {
    @Bean
    public EntityManagerFactory entityManagerFactory() {
        LocalContainerEntityManagerFactoryBean emf = new LocalContainerEntityManagerFactoryBean();
        emf.setPersistenceUnitName("persistence");
        emf.afterPropertiesSet();
        return emf.getObject();
    }

    @Bean
    public EntityManager entityManager(EntityManagerFactory entityManagerFactory) {
        return entityManagerFactory.createEntityManager();
    }

    @Bean
    public BookDao bookDao() {
        return new BookDao();
    }

    @Bean
    public BookService bookService() {
        return new BookService();
    }

    @Bean
    public DataSource dataSource() {
        DriverManagerDataSource ds = new DriverManagerDataSource();
        ds.setDriverClassName("org.postgresql.Driver");
        ds.setUrl("jdbc:postgresql://localhost:5432/postgres");
        ds.setUsername("user");
        ds.setPassword("password");
        return ds;
    }

    @Bean
    public PlatformTransactionManager transactionManager(EntityManagerFactory entityManagerFactory) {
        return new JpaTransactionManager(entityManagerFactory);
    }
}

在 BookDao 类中,如果我注释掉事务部分,则新书不会添加到数据库中。

请帮助我,我尝试解决这个问题两天了。据我所知,如果方法是私有的,或者是从同一个类调用的,则事务性不起作用。但这里的情况并非如此。

java spring jpa transactions entitymanager
1个回答
0
投票

你不应该在@Transactional方法中使用entityManager.getTransaction().begin()和entityManager.getTransaction().commit(),@Transactional注解足以用于事务。

© www.soinside.com 2019 - 2024. All rights reserved.