@Transactional注解失效但手动事务正常的JPA问题求助
JTA @Transactional注解查询返回空列表,手动事务正常的问题
我在进行JPA相关测试时遇到了一个无法解决的问题——手动编写事务的方法可以从PostgreSQL数据库中正常查询到Customer列表,但使用JTA的@Transactional注解的方法却返回空列表。
手动事务实现代码
package com.example.demo.service; import com.example.demo.dto.CustomerDto; import com.example.demo.mapper.CustomerMapper; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.EntityManager; import jakarta.persistence.EntityManagerFactory; import jakarta.persistence.Persistence; import jakarta.persistence.PersistenceContext; import jakarta.transaction.Transactional; //import javax.transaction.Transactional; import models.Customer; import java.util.ArrayList; import java.util.List; @ApplicationScoped public class CustomerRepository { EntityManagerFactory entityManagerFactory = null; EntityManager entityManager = null; public List<CustomerDto> findAllManual() { entityManagerFactory = Persistence.createEntityManagerFactory("jpa-postgres"); entityManager = entityManagerFactory.createEntityManager(); entityManager.getTransaction().begin(); List<Customer> customers = entityManager.createQuery("SELECT c FROM Customer c", Customer.class) .getResultList(); List<CustomerDto> customerDtos = new ArrayList<>(); customers.forEach(t -> customerDtos.add(CustomerMapper.toDto(t))); System.out.println("Komt hier wel. Print evt entity manager: " + entityManager); System.out.println("Komt hier wel. Print evt customers: " + customers); System.out.println("Komt hier wel. Print evt customersDTO: " + customerDtos); entityManager.close(); return customerDtos; } }
这个方法可以正常返回客户列表,但以下使用@Transactional注解的方法却无法得到数据:
使用@Transactional的方法代码
package com.example.demo.service; import com.example.demo.dto.CustomerDto; import com.example.demo.mapper.CustomerMapper; import jakarta.enterprise.context.ApplicationScoped; import jakarta.persistence.Persistence; import jakarta.persistence.PersistenceContext; import jakarta.transaction.Transactional; //import javax.transaction.Transactional; import models.Customer; import java.util.ArrayList; import java.util.List; @ApplicationScoped public class CustomerRepository { @PersistenceContext(unitName = "jpa-postgres") private EntityManager em; @Transactional public List<CustomerDto> findAll() { List customers = em.createQuery("SELECT c FROM Customer c", Customer.class) .getResultList(); List<CustomerDto> customerDtos = new ArrayList<>(); customers.forEach(t -> customerDtos.add(CustomerMapper.toDto((Customer) t))); System.out.println("Komt hier wel. Print evt entity manager: " + em); System.out.println("Komt hier wel. Print evt customers: " + customers); System.out.println("Komt hier wel. Print evt customersDTO: " + customerDtos); return customerDtos; } }
此方法返回空列表,我推测问题在于@Transactional方法没有正确连接数据库,但无法确定具体原因。
persistence.xml配置
<?xml version="1.0" encoding="UTF-8" standalone="yes"?> <persistence xmlns="https://jakarta.ee/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="https://jakarta.ee/xml/ns/persistence https://jakarta.ee/xml/ns/persistence/persistence_3_0.xsd" version="3.0"> <persistence-unit name="jpa-postgres"> <class>models.Customer</class> <properties> <property name="jakarta.persistence.jdbc.driver" value="org.postgresql.Driver" /> <property name="jakarta.persistence.jdbc.url" value="jdbc:postgresql://localhost:5432/filmland" /> <property name="jakarta.persistence.jdbc.user" value="postgres" /> <property name="jakarta.persistence.jdbc.password" value="root" /> <property name="hibernate.dialect" value="org.hibernate.dialect.PostgreSQLDialect" /> <property name="hibernate.show_sql" value="true" /> <property name="hibernate.format_sql" value="true" /> <property name="jakarta.persistence.schema-generation.database.action" value="create" /> </properties> </persistence-unit> </persistence>
两种方式使用的都是同一个"jpa-postgres"持久化单元,日志输出如下:
手动方法日志
16:20:02,343 INFO [stdout] (default task-1) Hibernate: 16:20:02,343 INFO [stdout] (default task-1) select 16:20:02,343 INFO [stdout] (default task-1) c1_0.id, 16:20:02,343 INFO [stdout] (default task-1) c1_0.email, 16:20:02,343 INFO [stdout] (default task-1) c1_0.password 16:20:02,344 INFO [stdout] (default task-1) from 16:20:02,344 INFO [stdout] (default task-1) customer c1_0 16:20:02,347 INFO [stdout] (default task-1) Komt hier wel. Print evt entity manager: SessionImpl(394828776<open>) 16:20:02,348 INFO [stdout] (default task-1) Komt hier wel. Print evt customers: [Customer(id=1, email=kees@kees.com, password=mooiman), Customer(id=2, email=jan@jan.com, password=mooieding)] 16:20:02,348 INFO [stdout] (default task-1) Komt hier wel. Print evt customersDTO: [com.example.demo.dto.CustomerDto@52fb491a, com.example.demo.dto.CustomerDto@76e5d921]
@Transactional方法日志
[2023-11-16 04:14:59,878] Artifact demo:war exploded: Deploy took 2,428 milliseconds 16:16:36,579 INFO [stdout] (default task-1) Hibernate: 16:16:36,579 INFO [stdout] (default task-1) select 16:16:36,579 INFO [stdout] (default task-1) c1_0.id, 16:16:36,580 INFO [stdout] (default task-1) c1_0.email, 16:16:36,580 INFO [stdout] (default task-1) c1_0.password 16:16:36,580 INFO [stdout] (default task-1) from 16:16:36,580 INFO [stdout] (default task-1) customer c1_0 16:16:36,586 INFO [stdout] (default task-1) Komt hier wel. Print evt entity manager: org.jboss.as.jpa.container.TransactionScopedEntityManager@2d71f100 16:16:36,587 INFO [stdout] (default task-1) Komt hier wel. Print evt customers: [] 16:16:36,587 INFO [stdout] (default task-1) Komt hier wel. Print evt customersDTO: []
希望有人能帮我理解这一现象的原因,以及我的@Transactional实现哪里出错了?
内容的提问来源于stack exchange,提问作者DixyNL
相关产品推荐
相关产品推荐

