Should I clear PersistenceContext with Singleton/Schedule? - jpa

Let's say I have an EJB for scheduled job.
#Singleton
#Startup
public class MySchedule {
#Schedule
public void doSomething() {
// select oldest 8192 entities (MyEntity.class)
// and process them
entityManager.clear(); // should I do this?
}
#PersistenceContext
private EntityManager entityManager;
}
Is it possible those selected entities are kept in the entityManager? Should(Ought) I clear it?

Related

Is it possible to pass EntityManager as a parameter through multiple beans?

I know i can do the following :
public class MyDao{
private EntityManager em;
public void setEm(EntityManager em){
this.em = em;
}
...
and then, using #PostConstuct to pass the EntityManager
public class MyBean{
private EntityManager em;
#Inject
private MyDao myDao;
#PostConstruct
private void init(){
myDao.setEm(em);
}
...
But due to my application's architecture restriction i cannot directly inject MyDao into MyBean, i should pass by MyBusinessDao Class, so i tried the following but i'm getting a nullPointerExeception on the value of EntityManager in MyDao :
public class MyBean{
private EntityManager em;
public MyBean(){
em = createEntityManager();
}
private EntityManager createEntityManager(){
//dynamically create the EntityManager
}
#Inject
private MyBusinessDao myBusinessDao;
#PostConstruct
private void init(){
myBusinessDao.setEm(em);
}
...
and in MyBusinessDao i inject MyDao:
public class MyBusinessDao {
private EntityManager em;
#Inject
private MyDao myDao;
#PostConstruct
private void init(){
myDao.setEm(em);
}
...
I should mention that i'm not using a J2EE container
You can implement an CDI Producer Method for providing the EntityManager via CDI injection.
#ApplicationScoped
class EntityManagerProducer {
#PersistenceContext(...)
private EntityManager em;
#Produces
#RequestScoped
public EntityManager produceEm() {
return em;
}
}
You can also inject the EntityManagerFactory and call emf.createEntityManager() in the producer method and implement an CDI-Disposer method, which closes the EntityManager before the scope is finished.
public void dispose(#Disposes EntityManager em) { ... }
If you have multiple persistence contexts, then implement a producer method for each persistence context and qualify them with a CDI-Qualifier.
I resolved it this way :
public class MyBusinessDao {
private EntityManager em;
#Inject
private MyDao myDao;
private void setEm(EntityManager em){
this.em = em;
//and here i call the setEm method of myDao also
myDao.setEm(em);
}
...

How to use different EntityManager based on condition at runtime?

My congfiguration is like below:
The abstract class:
public abstract class AbstractFacade<T> {
private Class<T> entityClass;
public AbstractFacade(Class<T> entityClass) {
this.entityClass = entityClass;
}
protected abstract EntityManager getEntityManager();
public T find(Object id) {
return getEntityManager().find(entityClass, id);
}
// other methods create(T), edit(T), ...
The Ejb that extends the abstract class (i have many others EJBs and about 12 different persistence units):
#Stateless
public class FilesDao extends AbstractFacade<Files> {
#PersistenceContext(unitName = "myfirstPU")
private EntityManager firstEm;
#PersistenceContext(unitName = "mysecondPU")
private EntityManager secondEm;
// i have more than two persistenceUnit ...
#Override
protected EntityManager getEntityManager() {
return firstEm; // or secondEm based on condition
}
public FilesDao() {
super(Files.class);
}
public Files findByFileref(String inFileRef) {
try {
Query q = firstEm.createNamedQuery("Files.findByFileref"); // or secondEm based on condition
q.setParameter("fileref", inFileRef);
Files file = (Files) q.getSingleResult();
return file;
} catch (NoResultException e) {
return null;
}
}
I want to use FilesDao like this :
#Stateless
#LocalBean
public class FileBusiness {
#EJB
FilesDao fileDao;
public void myMethod(){
if(condition1){
//use the FileDao with the EnityManager **firstEm**
}
else if(condition2){
//use the FileDao with the EnityManager **secondtEm**
}
...
}
Is there a way to achieve that ?
I read about using CDI with produces method.
CDI-Producers are not that hard, see the following example.
The following classes are CDI-Qualifier annotations, which are used to distinguish implementations.
#Retention(RetentionPolicy.RUNTIME)
#Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR })
#Qualifier
public #interface MyfirstPUQualifier { }
#Retention(RetentionPolicy.RUNTIME)
#Target({ TYPE, METHOD, FIELD, PARAMETER, CONSTRUCTOR })
#Qualifier
public #interface MysecondPUQualifier { }
The following is a CDI-Bean which injects the different EntityManagers and implements producer methods, making the two EntityManagers available to CDI, distinguished via CDI-Qualifiers
#ApplicationScoped
class MYProducer {
#PersistenceContext(unitName = "myfirstPU")
private EntityManager firstEm;
#PersistenceContext(unitName = "mysecondPU")
private EntityManager secondEm;
#Produces
#RequestScoped
#MyfirstPUQualifier
public EntityManager produceMyfirstPU(){
return firstEm;
}
#Produces
#RequestScoped
#MysecondPUQualifier
public EntityManager produceMysecondPU(){
return secondEm;
}
}
The following shows a CDI-Bean injecting both EntityManagers. This could be extracted to an abstract base class, because maybe needed by other DAOs as well.
#Stateless
public class FileDao {
#Inject
#MyfirstPUQualifier
private EntityManager emFirst;
#Inject
#MysecondPUQualifier
private EntityManager emSecond;
public void myDaoMEthod(){
final EntityManager em = getEntityManager();
...
}
private EntityManager getEntityManager(){
if(condition1){
return emFirst;
}
else if(condition2){
return emSecond;
}
}
}
No can use the FileDao bean without taking care what EntityManager to use, because shouldn't be decided in this bean anyway
#Stateless
#LocalBean
public class FileBusiness {
#EJB
FilesDao fileDao;
public void myMethod(){
// FileDao will decide what entity manager to use
fileDao.doStruff();
}
}

CDI with EntityListener and timing issue?

I'm trying to do this.
public class MyEntityListener {
#PrePersist
private void onPrePersist(final Object object) {
// set object with value fetched via onPostConstruct
}
#PostConstruct
private void onPostConstruct() {
// fetch some value using entityManager
}
#PersistenceContext
private EntityManager entityManager;
}
When I persist and instance via EJB, the entityManager is different instance from that of the EJB.
onPrePersist is executed (before or) regardless of postConstruct.
Is this normal?

PersistanceContext on NonServlet class

I have the following...
public class TestServlet extends HttpServlet {
#PersistenceContext
private EntityManager em;
...
}
#Stateless
#LocalBean
public class DeviceRegistrationPersister {
#PersistenceContext(unitName="deviceReg")
private EntityManager em;
...
}
The first one gets the entity manager just fine, however, the second the entity manager is null. Can someone help with what is going on?

children extended from parent DAO

I have a problem. I have a parent DAO:
public abstract class ParentDAO<T> {
#PersistenceContext
private EntityManager entityManager;
public EntityManager getEntityManager() {
return entityManager;
}
public void setEntityManager(EntityManager entityManager) {
this.entityManager = entityManager;
}
private EntityManager em() {
if (entityManager == null)
throw new IllegalStateException("The entity manager is not set");
return entityManager;
}
}
from which extends another children DAOs.
When I want to do some operation with children entity in children DAO, I must get EntityManager object from parent class or change the entityManager object declaration to protected which is bad OOP design. Is there another way to do this? Because when I have 100 DAO children's then I must get the entityManager from parent DAO for every new children.
yes incase you are using spring, you can just use "parent" attribute to give the base bean id.... so create one base bean object in this case entity manager and add it as parent in ur subclassed bean declarations.... look for extends + parent in spring bean declaration.