0

Ich benutze Guice, um EntityManager injizieren. Wenn ich die Übertragung des injected entityManager beginne, passiert auf der BD-Seite nichts: keine Transaktion !!! Kannst du mir helfen, herauszufinden, was vor sich geht?Commit EntityManager Transaktion mit @Transactional - Guice

Hier ist mein Code:

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> 

Die InjectorListener Klasse:

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

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

Die persistenceModule Klasse:

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

Die GuiceModule c Mädchen:

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

Die RestModule Klasse:

public class RestModule erweitert 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); 
    } 
} 

und schließlich die WebService (jeresy) Aufruf:

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

Antwort

1

Sie müssen wahrscheinlich Fügen Sie den Filter persistent hinzu. Dies wird Sie auch davon abhalten, Transaktionen manuell zu verwalten. Wenn Sie den Filter nicht verwenden, können Sie weiterhin UnitOfWork injizieren, um Transaktionen zu erstellen. Wenn Sie jpa persist verwenden, sollten Sie userTransactions nicht verwalten.

Dies ist ein benutzerdefinierter Filter, der außerdem einen Lebenszyklus hinzufügt, der beim Start automatisch mit benutzerdefiniertem Code und einem Builder für Map-Binder gestartet wird. Es ist nur für die Gründlichkeit da. Es ist nicht Teil des guice api, sondern eher dem Lifecycle Listener von spring. Ich habe keinerlei Frühlingsabhängigkeiten.

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

Beispiel für das Hinzufügen eines Filters zum Modul.

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

Beispiel für die Verwendung der Arbeitseinheit zur Verwaltung der Transaktion.

@Inject 
UnitOfWork unitOfWork; 
public void doSomething() { 
    unitOfWork.begin(); 
    try { 
     dao.saveState(someobject); 
    } finally { 
     unitOfWork.end(); 
    } 
} 
+0

Hallo Chris, ich habe einen einfachen GuiceFilter hinzugefügt und es funktioniert;): filter ("/ *"). Through (PersistFilter.class); Danke – taboubim

Verwandte Themen