
full-hibernate-plugin-for-struts2 - issue #26
detectAndCloseHibernateCoreSessionCreatedLater has no effect
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 :)
Comment #1
Posted on Nov 5, 2010 by Quick HorseSorry, it's inside intercept() not inject().
Comment #2
Posted on Nov 5, 2010 by Quick HorseAlso, 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);
}
}
...
}
Status: New
Labels:
Type-Defect
Priority-Medium