Sunday, November 15, 2009

Solution to SunTechDays Java Persisitence problem

I am a fan of Arun Gupta's technical screencast on various J2EE subjects and API. Recently I was looking for a Ajax wiring to a mashup and I turned to Arun Gupta's Screencast #Web7: Creating Mashups with jMaki - A real-life RIA using jMaki (Sun Tech Days Event Map) at http://blogs.sun.com/arungupta/entry/sun_tech_days_event_map. Which very well describe about how to setup widgets from various toolkits in jMaki in NetBeans IDE. Well I was very much sure thats what I am looking for and I started to setup a test environment quickly to test out the tutorial. Unfortunately that didn't fly well and was keep getting issue with JPA issues. I tried various tests everyting points to the JPA (Java Persistence API). So I dwell deeper in to JPA and learned quickly that Netbeans by default ship with TopLink JPA for Derby database.

So I realised that we need a Servlet to complete the JPA. And I put up this simple servlet and vol ah, that resolve the issue. Like a silver bullet. So I present her the missing part in the tutorial. Hope this helps you..

I create a servlet in the SunTechDays project under a package suntech.servlet. I named my servlet servletdata.java. Once the IDE create the servlet and open it in the editor, right mouse click and select persistence and click Use Entity Manager. This will inject the PersistenceContext in the class.
@PersistenceContext(name = "persistence/LogicalName", unitName = "SunTechDaysPU")

and it will add this annotation resource for managing transaction boundaries:

@Resource
private javax.transaction.UserTransaction utx;

If you look little down, you will find that a default persist method has also been added, which looks like this...

private void persist(Object object) {
try {
Context ctx = (Context) new javax.naming.InitialContext().lookup("java:comp/env");
utx.begin();
EntityManager em = (EntityManager) ctx.lookup("persistence/LogicalName");
em.persist(object);
utx.commit();
} catch(Exception e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE,"exception caught", e);
throw new RuntimeException(e);
}
}


just modify the above code to look like this:
public TechdaysSchedule findByMonth(Date startDate) {
TechdaysSchedule schedule = null;
try {
Context ctx = (Context) new InitialContext().lookup("java:comp/env");
utx.begin();
EntityManager em = (EntityManager) ctx.lookup("persistence/LogicalName");
schedule = em.find(TechdaysSchedule.class, startDate);
utx.commit();
} catch (Exception e) {
Logger.getLogger(getClass().getName()).log(Level.SEVERE, "exception caught", e);
throw new RuntimeException(e);
}
return schedule;
}


And make sure you import java.util.Date; in the beginning of the servlet.
What I have done here is replaced the scope from private to public and replaced void with TechdaysSchedule. Replaced default persist method with the findByMonth and the parameter object with Date startDate. Then I initialize a schedule variable to TechdaysSchedule and set a value to schedule using this em.find(TechdaysSchedule.class, startDate) and I return the value of schedule. Thats it.

Hope this works for you and if any issue please post a response to this blogg...