当前位置: 首页 > 知识库问答 >
问题:

使用@Transactional-Guice提交EntityManager事务

颜宸
2023-03-14

我正在使用Guice注入EntityManager。当我提交注入实体管理器的操作时,BD端没有发生任何事情:没有事务通过!!!你能帮我弄清楚发生了什么吗?

这是我的代码:

网状物xml

  <filter>
    <filter-name>guiceFilter</filter-name>
    <filter-class>com.google.inject.servlet.GuiceFilter</filter-class>
    <async-supported>true</async-supported>
  </filter>

  <filter-mapping>
    <filter-name>guiceFilter</filter-name>
    <url-pattern>/*</url-pattern>
  </filter-mapping>

  <listener>
    <listener-class>ca.products.services.InjectorListener</listener-class>
  </listener>

Inject torListener类:

public class InjectorListener extends GuiceServletContextListener {
    @Override
    protected Injector getInjector() {

        return Guice.createInjector(
                new PersistenceModule(),
                new GuiceModule(),
                new RestModule());
    }
}

持久性模块类:

public class PersistenceModule implements Module {
    @Override
    public void configure(Binder binder) {
        binder
                .install(new JpaPersistModule("manager1")
                        .properties(getPersistenceProperties()));

        binder.bind(PersistenceInitializer.class).asEagerSingleton();
    }

    private static Properties getPersistenceProperties() {
        Properties properties = new Properties();
        properties.put("hibernate.connection.driver_class", "org.postgresql.Driver");
        properties.put("hibernate.connection.url", "jdbc:postgresql://localhost:5432/postgres");
        properties.put("hibernate.connection.username", "postgres");
        properties.put("hibernate.connection.password", "postgres");
        properties.put("hibernate.connection.pool_size", "1");
        properties.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");
        properties.put("hibernate.hbm2ddl.auto", "create");

        return properties;
    }
}

GuiceModule类:

public class GuiceModule extends AbstractModule {

    @Override
    protected void configure() {

        bind(MemberRepository.class).to(MemberRepositoryImp.class);
        bind(ProductRepository.class).to(ProductRepositoryImpl.class);
        bind(ShoppingBagRepository.class).to(ShoppingBagRepositoryImpl.class);
    }
}

RestModule类:

公共类RestModule扩展了JerseyServletModule{

    @Override
    protected void configureServlets() {

        HashMap<String, String> params = new HashMap<>();
        params.put(PackagesResourceConfig.PROPERTY_PACKAGES, "ca.products.services");
        params.put(JSONConfiguration.FEATURE_POJO_MAPPING, "true");
        params.put(ResourceConfig.FEATURE_DISABLE_WADL, "true");

        serve("/*").with(GuiceContainer.class, params);
    }
} 

最后是网络服务(jeresy)的电话:

    @Inject
    private Provider<EntityManager> em;

    @GET
    @Transactional
    @Path("/reset")
    public void resetData() {

        logger.info("Processing reset");
        try {

            em.get().getTransaction().begin();

            for (int i = 0; i < 10; i++) {
                em.get().persist(new Product("Product_" + i, "Desc_" + i));
            }
            em.get().flush();
            em.get().getTransaction().commit();

        } catch (Exception e) {
            throw new WebApplicationException(Response.Status.FORBIDDEN);
        }
    }

共有1个答案

蓟俊杰
2023-03-14

您可能需要添加一个持久化过滤器。这也将使您不必手动管理事务。如果不使用过滤器,仍然可以注入UnitOfWork来创建事务。如果您使用的是jpa persist,则不应管理用户事务。

这是一个自定义过滤器,它还添加了一个生命周期,它在启动时使用一些自定义代码和一个映射绑定器生成器自动启动。它只是为了彻底而存在。它不是guice api的一部分,但更类似于Spring的生命周期侦听器。我根本没有任何Spring依赖项。

@Singleton
public final class JpaPersistFilter implements Filter {

    private final UnitOfWork unitOfWork;
    private final PersistServiceLifecycle persistService;

    @Inject
    public JpaPersistFilter(UnitOfWork unitOfWork, PersistServiceLifecycle persistService) {
        this.unitOfWork = unitOfWork;
        this.persistService = persistService;
    }

    public void init(FilterConfig filterConfig) throws ServletException {
        // persistService.start();
    }

    public void destroy() {
        persistService.stop();
    }

    public void doFilter(final ServletRequest servletRequest, final ServletResponse servletResponse,
            final FilterChain filterChain) throws IOException, ServletException {

        unitOfWork.begin();
        try {
            filterChain.doFilter(servletRequest, servletResponse);
        } finally {
            unitOfWork.end();
        }
    }

    /**
     * Extra lifecycle handler for starting and stopping the service. This
     * allows us to register a {@link Lifecycle} with the
     * {@link LifecycleListener} and not have to worry about the service being
     * started twice.
     * 
     * @author chinshaw
     *
     */
    @Singleton
    public static class PersistServiceLifecycle implements Lifecycle {

        private final PersistService persistService;

        private volatile boolean isStarted = false;

        @Inject
        public PersistServiceLifecycle(PersistService persistSerivce) {

            this.persistService = persistSerivce;
        }

        @Override
        public boolean isRunning() {
            return isStarted;
        }

        @Override
        public void start() {
            if (!isStarted) {
                persistService.start();
                isStarted = true;
            }
        }

        @Override
        public void stop() {
            persistService.stop();
            isStarted = false;
        }
    }
}

向模块添加筛选器的示例。

@Override
protected void configureServlets() {
    filter("/api/*").through(JpaPersistFilter.class);
}

使用工作单元管理事务的示例。

@Inject
UnitOfWork unitOfWork;
public void doSomething() {
    unitOfWork.begin();
    try {
         dao.saveState(someobject);
    } finally {
        unitOfWork.end();
    }
}
 类似资料:
  • 我正在尝试使用H2数据库使用maven来构建代码来学习Spring, Hibernate。目前我有一些问题,如何正确使用@Transactional注释来自动启动事务并在例如entityManager.persist成功或回滚时提交事务。 我的测试项目非常简单。POJO类是Person,包含名字、姓氏和电子邮件地址。有一个服务类PersonSerice,它是一个接口,提供CRUD函数来添加、更改、

  • 根据这个问题,当使用时,是事务范围。如果我理解正确,这意味着将为每个事务创建一个新的。使用时,建议使用提供所有绑定的,只需插入

  • 我已经开始使用这里描述的Guice方法级事务。我有一条消息,比如 从简短的描述中,我认为wis应该就足够了。但是我收到一个错误,因为没有启动任何事务。只有当我自己启动并提交它时,它才有效。 对象是由Guice在初始化程序中的应用程序的开始时创建的。每个请求使用相同的实例。 为什么它不起作用?

  • 我已经验证了@transaction方法是否正确放置,并且在调试堆栈中,我看到事务拦截器和实体管理器是根据对后端的请求创建的(因此没有guice持久性过滤器) 我的感觉表明问题在于会话上下文。我感觉(但我不能真正理解)它在多个请求上重用了我的持久性上下文。 我已经把一些框架放在一起,使这一切都能工作。我使用resteasy作为jax的实现者。guice(4.0beta4)作为cdi实现者,hibe

  • 我有两个具有不同PlatformTransactionManager、LocalContainerEntityManagerFactoryBean的数据源 我已经用org.springframework.transaction.annotation.transactional将manager方法注释为@transactional(value=“ReportingDataSource”) 我的存储库

  • 我正在用JPA和Hibernate做一些简单的测试,当我不希望的时候,我碰巧关闭了EntityManager。 这是我的测试主: DB助手: 实体和对应的DAO: 在商店里,当开始交易时,我得到以下信息: 未执行关机方法。为什么实体管理器关闭? 为了完整起见,以下是persistence.xml: