使用@Transactional提交EntityManager事务 - Guice

时间:2016-07-18 04:40:21

标签: dependency-injection jersey persistence guice entitymanager

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

这是我的代码:

Web.xml中

Yii::getAlias('@webroot')

InjectorListener类:

  <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>

persistenceModule类:

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

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

GuiceModule类:

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;
    }
}

RestModule类:

公共类RestModule扩展了JerseyServletModule {

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);
    }
}

最后是webservice(jeresy)致电:

    @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);
    }
} 

1 个答案:

答案 0 :(得分:1)

您可能需要添加一个持久性过滤器。这也将使您不必手动管理交易。如果您不使用过滤器,您仍然可以注入UnitOfWork来创建事务。如果你使用jpa persist,你不应该管理userTransactions。

这是一个自定义过滤器,它还添加了一个生命周期,它会在启动时自动启动,带有一些自定义代码和一个地图绑定器构建器。它只是为了彻底。它不是guice api的一部分,但更像是spring的生命周期监听器。我根本没有任何弹簧依赖。

rh_redirect_response

向模块添加过滤器的示例。

@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);
}
相关问题