package au.com.vaadinutils.dao;
import java.util.concurrent.Callable;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.Future;
/**
* Creates a Thread that has its own private EntityManager attached.
*
* This class should be used if you need to access a Dao object in a background
* thread that doesn't have an entity manager injected. This class injects the
* em into the thread.
*
* @author bsutton
*
*/
final public class EntityManagerThread<T>
{
private final Future<T> future;
/**
* Create an thread with a copy of the current threads UI (because you can't
* get the UI from within the new thread), inject an entity manager and
* starts a JPA Transaction then executes the callable on the new thread.
*
* The callable can optionally return a result of type T which can be
* retrieved by calling get().
*
* @param ui
* @param callable
*/
public EntityManagerThread(CallableUI<T> callable)
{
this((Callable<T>) callable);
}
/**
* Injects an entity manager and starts a JPA Transaction and then runs your
* callable.
*
* The callable can optionally return a result of type T which can be
* retrieved by calling get().
*
* @param ui
* @param callable
*/
public EntityManagerThread(final Callable<T> callable)
{
ExecutorService executor = Executors.newFixedThreadPool(1);
Callable<T> thread = new Callable<T>()
{
@Override
public T call() throws Exception
{
return EntityManagerProvider.setThreadLocalEntityManager(new EntityWorker<T>()
{
@Override
public T exec() throws Exception
{
return callable.call();
}
});
}
};
future = executor.submit(thread);
executor.shutdown();
}
/**
* Waits until the thread completes and returns the results of the thread.
*
* If the thread throws an exception calling this method will result in the
* original exception being re-thrown so you can catch it and do something
* useful with it.
*
* @return the results of the callable.
* @throws InterruptedException
* @throws ExecutionException
*/
public T get() throws InterruptedException, ExecutionException
{
return this.future.get();
}
}