使用@Transactional 提交 EntityManager 事务 - Guice
Commit EntityManager Transaction using @Transactional - Guice
我正在使用 Guice 注入 EntityManager。
当我提交注入的 entityManager 的交易时,BD 端没有发生任何事情:没有交易通过!!!你能帮我弄清楚发生了什么事吗?
这是我的代码:
Web.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>
InjectorListener class:
public class InjectorListener extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(
new PersistenceModule(),
new GuiceModule(),
new RestModule());
}
}
持久化模块class:
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 class :
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 class :
public class 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);
}
}
您可能需要添加持久过滤器。这也将使您不必手动管理交易。如果您不使用过滤器,您仍然可以注入 UnitOfWork 来创建交易。如果您使用的是 jpa persist,则不应管理 userTransactions。
这是一个自定义过滤器,它还添加了一个生命周期,它在启动时使用一些自定义代码和一个地图活页夹生成器自动启动。它只是为了彻底。它不是 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();
}
}
我正在使用 Guice 注入 EntityManager。 当我提交注入的 entityManager 的交易时,BD 端没有发生任何事情:没有交易通过!!!你能帮我弄清楚发生了什么事吗?
这是我的代码:
Web.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>
InjectorListener class:
public class InjectorListener extends GuiceServletContextListener {
@Override
protected Injector getInjector() {
return Guice.createInjector(
new PersistenceModule(),
new GuiceModule(),
new RestModule());
}
}
持久化模块class:
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 class :
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 class :
public class 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);
}
}
您可能需要添加持久过滤器。这也将使您不必手动管理交易。如果您不使用过滤器,您仍然可以注入 UnitOfWork 来创建交易。如果您使用的是 jpa persist,则不应管理 userTransactions。
这是一个自定义过滤器,它还添加了一个生命周期,它在启动时使用一些自定义代码和一个地图活页夹生成器自动启动。它只是为了彻底。它不是 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();
}
}