Wow - very cool. When do you think this patch will be released? And
would you be able to provide a brief code snippet of how to use/extend
this new class? My current setup is below which uses an
ExecuteAndWaitInterceptor to create a class that extends the
BackgroundProcess class.
Again thanks for all your work on this.
@Component
public class OpenSessionExecuteAndWaitInterceptor extends
ExecuteAndWaitInterceptor {
@Autowired
private transient EntityManagerFactory entityManagerFactory;
@Override
protected BackgroundProcess getNewBackgroundProcess(String arg0,
ActionInvocation arg1, int arg2) {
return new OpenSessionBackgroundProcess(arg0, arg1, arg2,
entityManagerFactory);
}
}
public class OpenSessionBackgroundProcess extends BackgroundProcess
implements Serializable {
private static final long serialVersionUID = 1L;
private final transient EntityManagerFactory entityManagerFactory;
// used for synchronization
protected boolean initializationComplete;
private transient Object lock = new Object();
public OpenSessionBackgroundProcess(String name, ActionInvocation
invocation, int threadPriority, EntityManagerFactory
entityManagerFactory) {
super(name, invocation, threadPriority);
this.entityManagerFactory = entityManagerFactory;
initializationComplete = true;
synchronized (lock) {
lock.notify();
}
}
protected void beforeInvocation() throws Exception {
while (!initializationComplete) {
try {
synchronized (lock) {
lock.wait(100);
}
} catch (InterruptedException e) {
// behavior ignores cause of re-awakening.
}
}
EntityManager em = entityManagerFactory.createEntityManager();
TransactionSynchronizationManager.bindResource(entityManagerFactory, new
EntityManagerHolder(em));
super.beforeInvocation();
}
protected void afterInvocation() throws Exception {
super.afterInvocation();
EntityManagerHolder emHolder = (EntityManagerHolder)
TransactionSynchronizationManager.unbindResource(entityManagerFactory);
EntityManagerFactoryUtils.closeEntityManager(emHolder.getEntityManager());
}
/**
* Override default readObject() method when deserializing
*
* @param serialized the serialized object
*/
private void readObject(ObjectInputStream serialized) throws
IOException, ClassNotFoundException {
serialized.defaultReadObject();
lock = new Object();
}
}
------ Original Message ------
From "Lukasz Lenart" <lukaszlen...@apache.org>
To "Struts Users Mailing List" <user@struts.apache.org>
Date 10/5/2022 2:12:20 AM
Subject Re: Race condition in recommended "OpenSessionBackProccess"
class
I refactored the BackgroundProcess and it should solve your problem,
yet it will require some coding.
https://github.com/apache/struts/pull/609
niedz., 2 paź 2022 o 13:09 Lukasz Lenart <lukaszlen...@apache.org> napisał(a):
śr., 28 wrz 2022 o 16:15 Burton Rhodes <burtonrho...@gmail.com> napisał(a):
>
> Lukasz -
> I have queried you on this before, but I am trying to get to the bottom of
> why the class Dale Newfield recommended (many years ago) to solve the Open
> Session during ExecuteAndWait problem gives me issues from time to time
> [1]. Recently (as our user base grows) I am getting NPEs more and more on
> the synchronized "lock" variable. I posed the question to StackExchange
> [2], and one contributor suggested there is a race condition by extending
> the BackgroundProcess class.
>
> Full disclosure, this kind of problem starts to get over my head, so I am
> wondering if you might have some guidance on how I can once and for all fix
> this issue.
>
> As always, thanks in advance.
>
> [1]
>
https://cwiki.apache.org/confluence/display/WW/HibernateAndSpringEnabledExecuteAndWaitInterceptor
>
> [2]
>
https://stackoverflow.com/questions/73858251/how-to-properly-use-a-lock-variable-for-synchronization-in-a-serializable-clas?noredirect=1#comment130421653_73858251
As far as I understand the answer on SO, we must change how the
BackgroundProcess is initialised - instead of using a constructor
based logic, move it into a method or so.
Would you mind registering a ticket in JIRA with the above description?
Regards
--
Łukasz
+ 48 606 323 122 http://www.lenart.org.pl/
---------------------------------------------------------------------
To unsubscribe, e-mail: user-unsubscr...@struts.apache.org
For additional commands, e-mail: user-h...@struts.apache.org