Hi,
ich beschäftige mich gerade mit JEE und habe da ein Verständnisproblem:
Eclipse legt mir für das Ejb-Projekt auch ein Ejb-Client-jar an in dem alle APis liegen d.h. die RemoteInterfaces der SessionBeans. Soweit alles klar. Der Client benötigt ja nur die Interfaces, um per Jndi (RMI) auf den Service zu zugreifen.
Wenn ich jetzt aber in einem RemoteInterface eine Persistent Entity (JPA) zurück geben will gibt das Probleme, denn die Perstitent Entites liegen im Ejb-Jar und das Ejb-Jar hat schon eine Dependency auf das Client-Jar d.h. ich kriege hier nen Classpath-Cycle.
Aber wie soll das sonst funktionieren? Ich will dem Client ja auch nicht das EJb-Jar mitgeben nur damit er die Persistent Entities nutzen kann.
Wie löst man das am sinnvollsten?
Mein zweites Problem bezieht sich auf das DAO-Pattern innerhalb einer JEE-Application. Im Moment nutze ich ein GenericDAO als Basis für alle DAOs in das der EntityManager injiziert wird:
Alle DaoLocalInterfaces erben dann von GenericDaoImpl und implementieren GenericDAO:
Die einzelnen DAOs können dann in die Services (Stateless SessionBeans) injiziert werden. Funktioniert auch alles wunderbar. Ich habe eine saubere Trennung von Persistenz und Logik und kann sehr einfach Unittests für meine Services schreiben. Die DAOs lassen sich einfach mocken, da sie nur injiziert werden und keien Logik enthalten.
Wie wird das denn normalerweise in JEE-Applications gehandhabt? Ich habe vorher Spring verwendet und da wird das so gemacht wie eben beschrieben. Wir hatten hier ja schon mehrmals die Diskussion zu DAO vs. Repistories nur kann ich bei den Repositories keinen wirklichen Unterschied erkennen zu DAOs.
Aber auf eine Persitenzkappselung will ich auch nicht verzichten. Denn wenn ich überall in alle Serviceklassen einen EntityManager injizieren lasse habe ich keine Trennung der schichten mehr.
ich beschäftige mich gerade mit JEE und habe da ein Verständnisproblem:
Eclipse legt mir für das Ejb-Projekt auch ein Ejb-Client-jar an in dem alle APis liegen d.h. die RemoteInterfaces der SessionBeans. Soweit alles klar. Der Client benötigt ja nur die Interfaces, um per Jndi (RMI) auf den Service zu zugreifen.
Wenn ich jetzt aber in einem RemoteInterface eine Persistent Entity (JPA) zurück geben will gibt das Probleme, denn die Perstitent Entites liegen im Ejb-Jar und das Ejb-Jar hat schon eine Dependency auf das Client-Jar d.h. ich kriege hier nen Classpath-Cycle.
Aber wie soll das sonst funktionieren? Ich will dem Client ja auch nicht das EJb-Jar mitgeben nur damit er die Persistent Entities nutzen kann.
Wie löst man das am sinnvollsten?
Mein zweites Problem bezieht sich auf das DAO-Pattern innerhalb einer JEE-Application. Im Moment nutze ich ein GenericDAO als Basis für alle DAOs in das der EntityManager injiziert wird:
Code:
@Stateless
public class GenericDAOImpl<T extends Serializable, PK extends Serializable> implements GenericDAO<T, PK>
{
@PersistenceContext
protected EntityManager em;
private Class<T> domainClass;
@SuppressWarnings("unchecked")
protected Class<T> getDomainClass()
{
if (null == domainClass)
{
ParameterizedType thisType = (ParameterizedType) getClass().getGenericSuperclass();
domainClass = (Class<T>) thisType.getActualTypeArguments()[0];
}
return domainClass;
}
public T load(PK id)
{
return em.find(getDomainClass(), id);
}
public void refresh(T t)
{
em.refresh(t);
}
public void persist(T t)
{
em.persist(t);
}
public void remove(T t)
{
em.remove(t);
}
@SuppressWarnings("unchecked")
public List<T> getAll()
{
return em.createQuery("from " + getDomainClass().getName()+ " x").getResultList(); //$NON-NLS-1$ //$NON-NLS-2$
}
public void deleteById(PK id)
{
Object obj = load(id);
em.remove(obj);
}
public void deleteAll()
{
em.createQuery("delete " + getDomainClass().getName()).executeUpdate(); //$NON-NLS-1$
}
public int count()
{
Integer count = (Integer) em.createQuery("select count(*) from "+ getDomainClass().getName() + " x").getSingleResult(); //$NON-NLS-1$ //$NON-NLS-2$
return count.intValue();
}
}
Alle DaoLocalInterfaces erben dann von GenericDaoImpl und implementieren GenericDAO:
Code:
public interface GenericDAO<T, P>
{
public T load(P id);
public void refresh(T t);
public void persist(T t);
public void remove(T t);
public List<T> getAll();
public void deleteById(P id);
public void deleteAll();
public int count();
}
Die einzelnen DAOs können dann in die Services (Stateless SessionBeans) injiziert werden. Funktioniert auch alles wunderbar. Ich habe eine saubere Trennung von Persistenz und Logik und kann sehr einfach Unittests für meine Services schreiben. Die DAOs lassen sich einfach mocken, da sie nur injiziert werden und keien Logik enthalten.
Wie wird das denn normalerweise in JEE-Applications gehandhabt? Ich habe vorher Spring verwendet und da wird das so gemacht wie eben beschrieben. Wir hatten hier ja schon mehrmals die Diskussion zu DAO vs. Repistories nur kann ich bei den Repositories keinen wirklichen Unterschied erkennen zu DAOs.
Aber auf eine Persitenzkappselung will ich auch nicht verzichten. Denn wenn ich überall in alle Serviceklassen einen EntityManager injizieren lasse habe ich keine Trennung der schichten mehr.