wangscript / warp-persist

Automatically exported from code.google.com/p/warp-persist
0 stars 0 forks source link

Not functional with Glassfish #34

Open GoogleCodeExporter opened 9 years ago

GoogleCodeExporter commented 9 years ago
What steps will reproduce the problem?
1. Setup the warp-persist in your guice configuration
2. Setup the session context filter from warp-persist
3. Launch several requests

What is the expected output? What do you see instead?

Expect the entity manager sessions to be closed.  They are not.

What version of the product are you using? On what operating system?

Version 2 snapshot on Windows 7/Vista.

Please provide any additional information below.

The problem is that warp-persist uses thread local storage to setup and tear 
down the entity manager instance used by a thread.  However, on 
Glassfish, the modified Tomcat's web server component is Grizzly and not 
Coyote.  Grizzly uses NIO and a thread pool to manage multiple connections 
from the same thread while a worker pool handles the requests themselves.

What occurs is that EntityManagerHolder will have a different value in the 
filter than it does in the client code since those are completely different 
threads.

What I did to work around the issue is roll my own solution that solves 
this problem by checking if we're the topmost transaction in my own 
@Transactional interceptor and clear the EntityManager from there.

Original issue reported on code.google.com by pjul...@gmail.com on 16 Sep 2009 at 1:42

GoogleCodeExporter commented 9 years ago
This should not affect anything because the filter and the servlet chain runs 
inside the same (worker) thread. 
Basically if this is the case hundreds of apps and libraries (including 
hibernate, spring etc.) would all stop 
functioning in glassfish. I imagine there is something else wrong--can you post 
your config please?

Note that Jetty also uses a NIO connector and works fine.

Original comment by dha...@gmail.com on 16 Sep 2009 at 2:02

GoogleCodeExporter commented 9 years ago
You're right.  I can't post the code but will continue my investigation.  I'm 
using 
gwt-dispatch, I'm wondering if that's the component that is switching out the 
threads.

Original comment by pjul...@gmail.com on 16 Sep 2009 at 2:07

GoogleCodeExporter commented 9 years ago
It's not gwt-dispatch since it's just not using other threads.  All I can say 
for now 
is that over time, more and more sessions stay open and the value found from 
EntityManagerHolder in the filter is null sometimes.

Original comment by pjul...@gmail.com on 16 Sep 2009 at 1:46

GoogleCodeExporter commented 9 years ago
I will try to figure this out and try to make a reduced test case

Original comment by pjul...@gmail.com on 16 Sep 2009 at 1:46

GoogleCodeExporter commented 9 years ago
I am developing a GWT project and use the following:
   1) GWT (from trunk)
   2) gwt-dispatch
   3) gwt-presenter
   3) Guice 2
   4) warp-persist 2 (from svn)
   5) Application Server: GlassFish v3 - B62    

The settings are as follows:

web.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE web-app PUBLIC "-//Sun Microsystems, Inc.//DTD Web Application 
2.3//EN"
"http://java.sun.com/dtd/web-app_2_3.dtd">
<web-app>
    <display-name>GWT-Maven-Archetype</display-name>

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

    <filter>
        <filter-name>sessionPerFilter</filter-name>
        <filter-class>com.wideplay.warp.persist.PersistenceFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>guiceFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>

    <filter-mapping>
        <filter-name>sessionPerFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <listener>

<listener-class>com.logikas.hipokrates.gwt.server.guice.HipokratesServletContext
Listener</listener-class>
    </listener>
</web-app>

persistence.xml:
<?xml version="1.0" encoding="UTF-8"?>
<persistence version="1.0" xmlns="http://java.sun.com/xml/ns/persistence"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd">
  <persistence-unit name="HipokratesPU" transaction-type="RESOURCE_LOCAL">
    <provider>org.hibernate.ejb.HibernatePersistence</provider>
    <non-jta-data-source>HipokratesDS</non-jta-data-source>
    <class>com.logikas.hipokrates.gwt.domain.entity.Person</class>
  </persistence-unit>
</persistence>

HipokratesDS: The datasource is configured in Glassfish.

HipokratesServletContextListener:

public class HipokratesServletContextListener extends 
GuiceServletContextListener {
    @Override
    protected Injector getInjector() {
        return Guice.createInjector(
                PersistenceService
                .usingJpa()
                .across(UnitOfWork.REQUEST)
                .buildModule(),new DispatchServletModule());
        }
}

DispatchServletModule:
public class DispatchServletModule extends ServletModule{
    @Override
    protected void configureServlets() {
        install(new HipokratesPersistenceModule());
        serve("/com.logikas.hipokrates.gwt.Application/dispatch")
       .with(StandardDispatchServiceServlet.class);
    }
}

HipokratesPersistenceModule:
public class HipokratesPersistenceModule extends AbstractModule {
    @Override
    protected void configure() {
        bindConstant().annotatedWith(JpaUnit.class).to("HipokratesPU");
        install(new HipokratesServiceModule());
    }
}

HipokratesServiceModule:

public class HipokratesServiceModule extends ActionHandlerModule {
    @Override
    protected void configureHandlers() {
        bindHandler( PersonAddRequest.class, PersonAddService.class );
    }
}

I have 3 problems with this:
    Problem 1) In the DAO, for example, if the EntityManager injected in the DAO
constructor gives NullPointerException in the Deploy Server.
    @Inject
    private final EntityManager em;

    public PersonDAO(EntityManager em) {
        this.em = em;
    }
The solution was:
  @Inject
  Provider<EntityManager> provider:

  public PersonDAO(){
  }

Do not know if it is right, but it works.

Problem 3) Hibernate validator not called, for example:

     @ Column (name = "surname")
     @ NOTNULL
     getSurname public String () (
         return surname;
     )

The DAO method is:

     @Transactional()
     public void add( Person person ) (
         provider.get().persist( person );
     )
If the value is null, the persistence is done without problems. What's wrong?

These are the libraries that I use:

1) hibernate-annotations-3.2.1.ga
2) hibernate-validator-3.1.0.GA
3) hibernate-core-3.3.0.SP1
4) persistence-api-1.0

Runtime Libraries:
1) hibernate-3.2.2.ga
2) hibernate-entity-manager-3.2.1.ga
3) hibernate-tools-3.2.0.ga
...
...

I hope I have given enough information.
Greetings

Original comment by csrina...@gmail.com on 26 Sep 2009 at 1:40

GoogleCodeExporter commented 9 years ago
Sorry, bad copy that piece of code, @ Inject this up in the constructor

private final EntityManager em;

@ Inject
public personDAO (EntityManager em) (
....
....

Attach a file with the exception.

Thx.

Original comment by csrina...@gmail.com on 26 Sep 2009 at 2:33

Attachments: