Technology(Java EE 6 with Glassfish 3.1, Netbeans 7.0)
I have an application client that access a db via JPA. No EJB
is involved. Now I need to add an web interface for this application client. So I will choose to use JSF 2.x
. I have some concern about design here, and I hope the community would help me out. So thanks to BalusC, I am able to use JPA in a stand alone client application by specify transaction-type=RESOURCE_LOCAL
in the persistence.xml. Below are demonstration:
EDIT the below codes has been edited base on BalusC suggestion
Here is my App Client main
public static void main(String[] args) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("CoreInPU");
EntityManager em = emf.createEntityManager();
EntityDAO entityDAOClient = new EntityDAOClient(em);
Main pgm = new Main();
try {
process(entityDAOClient);
} catch (Exception e) {
logger.fatal("", e);
}finally{
em.close();
emf.close();
}
}
public void process(EntityDAO entityDAO){
validatePDF(List<pdfFiles>);
processPDF(List<pdfFiles>, entityDAO);
createPrintJob(List<pdfFiles>, entityDAO);
}
public void processPDF(List<pdfFiles>, EntityDAO entityDAO){
for(File file : pdfFiles){
entityDAO.create(file);
}
}
Here is my DAO
interface class in my App Client
public interface EntityDAO {
public <T> T create(T t);
public <T> T find(Class<T> type, Object id);
public List findWithNamedQuery(String queryName);
public List findWithNamedQuery(String queryName, int resultLimit);
}
Here is the App Client DAO
public class EntityDAOClient implements EntityDAO {
private EntityManager em;
private static Logger logger = Logger.getLogger(EntityDAOClient.class);
public EntityDAOClient(EntityManager em) {
this.em = em;
}
@Override
public <T> T create(T t){
em.getTransaction().begin();
em.persist(t);
em.getTransaction().commit();
return t;
}
@Override
public <T> T find(Class<T> type, Object id){
em.getTransaction().begin();
T t = em.find(type, id);
em.getTransaction().commit();
return t;
}
...
}
And here is the persistence.xml
<persistence-unit name="CoreInPU" transaction-type="RESOURCE_LOCAL">
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>com.wf.docsys.core.entity.Acknowledgement</class>
<class>com.wf.docsys.core.entity.PackageLog</class>
<properties>
<property name="javax.persistence.jdbc.url" value="jdbc:mysql://localhost:3306/core"/>
<property name="javax.persistence.jdbc.password" value="root"/>
<property name="javax.persistence.jdbc.driver" value="com.mysql.jdbc.Driver"/>
<property name="javax.persistence.jdbc.user" value="xxxx"/>
<property name="eclipselink.ddl-generation" value="create-tables"/>
</properties>
</persistence-unit>
Now I need to add a web module on top of this. I know I need JTA
transaction type, so I create an EAR project call foo
with foo_ejb
and foo_war
in it. So my EJB look like this.
@Stateless
@LocalBean
public class CoreEJB implements EntityDAO{
@PersistenceContext(unitName = "CoreInWeb-ejbPU")
private EntityManager em;
//@Override
public <T> T create(T t) {
em.persist(t);
return t;
}
//@Override
public <T> T find(Class<T> type, Object id) {
return em.find(type, id);
}
...
}
Note that CoreInWeb-ejbPU
is the new persistence.xml unit name with JTA
transaction type. I also add my app client jar file to the foo_ejb
package. When I deploy I got this message Invalid ejb jar [foo-ejb.jar]: it contains zero ejb.
It is because of this @Stateless public class CoreEJB implements EntityDAO
. If I take the implements EntityDAO
out then it is deploy, but I need the EJB to be implements EntityDAO
so that in my managed bean I can do this
@ManagedBean
@RequestScoped
public class Bean {
@EJB
private CoreEJB coreEJB;
public Bean() {
}
public void runAppClientMainProcess() {
//The web interface can also kick off the same process as the app client
process(coreEJB);
}
// ...
}
How can I do this correctly? Please help
I know I might be asking too much here, but if you can base on my structure above, show me how to add a web module in, I would greatly appreciate it. Some codes would be awesome. I am still learning, so if my design is flaw, feel free to rip it, I will redesign everything if I am convince there are better way to accomplish this. Bottom line is, there are a set of business logic, and I want to access those via both application client
and web interface
. Like how glassfishv3 have web interface and admin console