ninada / full-hibernate-plugin-for-struts2

Automatically exported from code.google.com/p/full-hibernate-plugin-for-struts2
1 stars 0 forks source link

detectAndCloseHibernateCoreSessionCreatedLater has no effect #26

Open GoogleCodeExporter opened 8 years ago

GoogleCodeExporter commented 8 years ago
detect*CreatedLater methods are used inside inject() method like this:
{{{ 
 detectAndCommitHibernateTransactionCreatedLater(action);
 detectAndCloseHibernateCoreSessionCreatedLater(action);
}}}
These methods are defined in the following way:
{{{
 private synchronized void
 detectAndRollbackHibernateTransactionCreatedLater(Object targetObject)
 throws Exception {
     try {
         if (readedObjectsByRequest.get(ServletActionContext.getRequest())
                     .contains(targetObject))
             return;

         readedObjectsByRequest.get(ServletActionContext.getRequest())
             .add(targetObject);

 -----------------------------------------

 private synchronized void
 detectAndCloseHibernateCoreSessionCreatedLater(Object targetObject)
 throws SecurityException, NoSuchMethodException,
        IllegalArgumentException, IllegalAccessException,
        InvocationTargetException, ClassNotFoundException {

     if (readedObjectsByRequest.get(ServletActionContext.getRequest())
                 .contains(targetObject))
         return;

     readedObjectsByRequest.get(ServletActionContext.getRequest())
         .add(targetObject);
}}}

Thus, when both methods are called in a row the one that comes second has no 
effect for it's target object was already stored in the readedObjectsByRequest 
map by the first method.

What steps will reproduce the problem?

One way of reaching this code path is closing an injected session.

{{{
public class MyAction extends AcctionSupport {
    @SessionTarget
    Session session;

    public String execute() {
        session.close();
        return SUCCESS;
    }
}
}}}

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

I don't know what is readedObjectsByRequest used for. So, I can't say :)

Original issue reported on code.google.com by dnie...@gmail.com on 5 Nov 2010 at 6:00

GoogleCodeExporter commented 8 years ago
Sorry, it's inside intercept() not inject().

Original comment by dnie...@gmail.com on 5 Nov 2010 at 6:12

GoogleCodeExporter commented 8 years ago
Also, inside the implementation of detect*CreatedLater, the action will never 
be executed because isCandidadeClass() blacklist the value.

For example, in detectAndCloseHibernateCoreSessionCreatedLater, the block which 
closes the session is unreachable because fieldValue's class (SessionImpl) is 
being passed to isCandidadeClass which blacklists org.hibernate package.

 for (Field campo : campos) {
     if (campo.isEnumConstant())
         continue;

     // test for "singletons"
     campo.setAccessible(true);
     Object fieldValue = campo.get(targetObject);

     if ((fieldValue==null) || !isCandidadeClass(fieldValue.getClass()))
         continue;

     ...
     if (campo.getType().getName().equals(Session.class.getName())) {
          if (campo.isAnnotationPresent(SessionTarget.class)) {
              campo.setAccessible(true);
              Session hibernateSession = (Session) campo.get(targetObject);
              closeHibernateSession(hibernateSession);
          }
     }
     ...
 }

Original comment by dnie...@gmail.com on 5 Nov 2010 at 6:28