You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

@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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.06 01:47:06