Showing posts with label DAO. Show all posts
Showing posts with label DAO. Show all posts

Friday, August 17, 2012

Autobind All Tapestry5 services!

Norman Franke, Dmitry Gusev and a bunch of other guys in the Tapestry5 mailing list show us a very cool way to bind services via package traversal. No more binder declarations for DAO services several miles long.

The technique they showed made me want to smack my older self - Why didn't you think of that!? This autobind technique basically just needs a bit of planning - a "convention" if you will. The idea is to put the "implementation" package as a folder below your DAO interfaces. Typically, you would append an "Impl" tag to your DAO interfaces so for example: UserDAO = UserDAOImpl and then place them in the correct packages: com.myapp.dao for the DAO interfaces and then com.myapp.dao.impl for the DAO implementations. The rest is done in the AppModule of Tapestry5.

...
public static void Bind(ServiceBinder binder) throws ClassNotFoundException  
{  
   autoBindServices(binder, ProjectDAO.class.getPackage());  
   .....  
}  
private static void autoBindServices(ServiceBinder binder, Package interfacePackage) throws ClassNotFoundException  
{  
  List<Class<?>> interfaces = Utils.getClassesForPackage(interfacePackage.getName());  
  for(Class intf : interfaces)  
  {  
     String className = interfacesPackage.getName() + ".impl." + intf.getSimpleName() + "Impl";  
     try  
     {  
         Class impl = Class.forName(className);  
         binder.bind(intf, impl);  
     }  
     catch(ClassNotFoundException e)  
     {  
         logger.warn("Class not found during autobinding: {}", className);  
     }  
  }  
}
Very cool stuff.

Wednesday, October 28, 2009

Homer Simpson on Hibernate: DAO! (Part 2)

Let's pick it up where we left off; writing code for the implementation part of our dao.

To get started, we need to get the tapestry-hibernate lib to make it easy for us to get hibernate and tapestry talking. We are going to use maven for this.

Now open you pom.xml the project file folder and add this:

 <dependency>  
       <groupId>org.apache.tapestry</groupId>  
       <artifactId>tapestry-hibernate</artifactId>  
       <version>5.1.0.5</version>  
 </dependency>  

This should be in the dependencies part of the pom file. Once you save this, it will automatically get the files for you. Remember to connect to the internet. You gotta love Maven.

We got our library, now we have to actually write the implementation code - we start with creating an impl package within the dao package and creating two Java classes namely: AddressDAOimpl and LoginDAOimpl. This Java classes implement their respective DAO interfaces.

Here is part of that AddressDAOimple.java source code.
 import org.apache.tapestry5.ioc.annotations.Inject;  
 import org.hibernate.Session;  
 /**  
  *  
  * @author killertilapia  
  */  
 public class AddressDAOimpl implements AddressDAO {  
   @Inject  
   private Session session;  
   public void add(Address newAddress) {  
     session.save(newAddress);  
   }  
   public void delete(Address address) {  
     session.delete(address);  
   }  
   public List<Address> retrieveAll() {  
     return session.createCriteria(Address.class).list();  
   }  
   public void update(Address address) {  
     session.saveOrUpdate(address);  
   }  
 }  

LoginDAOimpl contains the same idea.

It's quite simple really since Hibernate hides almost all(if not all) of the database/sql/jbdc code from us. All we really need is that session object that we injected into the class. That session object is our link to the database - think of it as an instantace of hibernate.cfg.xml.

We got the database part working now all we need is for someway to make it available to the entire web application. Enter Inversion of Control or IOC. We simply expose this thing as a service and then we can inject it into any part of the web application where we need it just like that session object earlier.

Open AppModule.java file. It should be in the services package. We first bind the DAO interfaces with their implementation file. Then we "give advice" to it using HibernateTransactionAdviser interface. This way the advice method is configured to match against any service whose id ends with "DAO", such as "PersonDAO". The advisor scans the service interface and identifies any methods with the @CommitAfter annotation. Got all that?

Here's the bind:

 public static void bind(ServiceBinder binder)  
 {  
     binder.bind(AddressDAO.class, AddressDAOimpl.class);  
     binder.bind(LoginDAO.class, LoginDAOimpl.class);  
 }  

The advisor part:
 @Match("*DAO")  
 public static void adviseTransactions(HibernateTransactionAdvisor advisor, MethodAdviceReceiver receiver) {  
     advisor.addTransactionCommitAdvice(receiver);  
 }  

And here's the @CommitAfter annotation in the DAOs:

 public interface AddressDAO {  
   @CommitAfter  
   public void add(Address newAddress);  
   @CommitAfter  
   public List<Address> retrieveAll();  
   @CommitAfter  
   public void update(Address address);  
   @CommitAfter  
   public void delete(Address address);  
 }  

See...was that so bad?

Anyway, I am putting the code into a subversion repository so you can get your bloody claws into it. Again, if you don't know what a subversion repo educate yourself. You'll probably need a kenai.com. account. Make one, its free anyway and it integrates with Netbeans6.7 quite nicely.

Sunday, October 18, 2009

Homer Simpson on Hibernate: DAO! (Part 1)

Homer's got nothing to do with this - besides he's a nuclear technician not a web developer.

This where we add our database part of our addressbook web application. This part is actually pretty long so I am going to split it into two maybe three parts.

Let's get started...

We will be using a design pattern called Data Access Objects. We will inject this as a service, exposing it to the entire web application. We will also use Hibernate for this. This will further simplify our DAO approach. If you don't know or forgot what is a design pattern or even what is a DAO, educate yourself.

We already have all the pieces - we got the database, our webapp and our IDE - all  we need is to use these pieces and work our DAO.

We begin by creating our hibernate.cfg.xml file. This file will connect us to our database where we created earlier at the beginning of this tutorial series. Where we put the file is defined by the file layout of our Tapestry5 web application. Now...

  1. Go to the Other Sources node of our project browser and locate the default package,
  2. Right-click select New and then Other. 
  3. Look for the Hibernate folder and then select Hibernate Configuration Wizard.
  4. Just accept the defaults of the first two pages until you reach the third page of the wizard where you select the data source. Select New Database Connection and supply the details more or less like the screenshot.
You should be now look at a hibernate.cfg.xml file. The next part is where we add some optional bits to our hibernate.cfg.xml file to help us debug our code later. Trust me, better to do it now than later.We could remove this bits when we deploy or we could simply leave it. Almost all of the debugging code outputs into the console anyway.
  1. Open the hibernate.cfg.xml file if its not open(duh!) and locate Optional Properties 
  2. Open that up and we will add two new properties
  3. The first property is the hibernate.show_sql (should be the first item in the combo box) and set it to true.
  4. The second one is to set hibernate.format_sql to true. This basically just pretty prints our sql statements into the console.
We got our database connection, we should start making our entities. Entities? Well, entities are object equivalents of database tables. Right now, we should be able to create two entities which are address and login which are our two tables in our database.
  1. Go to the Source Package create a new file.
  2. Now, this part will not make sense to you but just work with me. Go to Persistence and select Entity Classes from Database.
  3. Select the correct connection and select both tables.
  4. In the Entity Classes part modify the package name into edu.addressbook.entities. Don't about the project not having any persistence unit and make sure that the Generate named query annotations is check.
  5. In the Mapping Options there is one thing you need to decide on though, its the collection type. The collection type basically defines how you are going to handle rows of records containing data retrieved from the database. Now don't you wish you should have paid more attention to Sir Jay's class on data structures and algorithms class during college. Anyhow, I am selecting List for this tutorial but it doesn't really matter what you choose as long you know how to handle that data structure.
You should be looking at something that looks like the screenshot #2 after finishing the wizard. If you look at the code inside the entities you should notice is basically a POJO with bits of annotations - lots of get and set methods.

With that, we start creating our abstract interfaces for our DAO. Abstract interfaces in DAO are simply Java interfaces and we need two - one for the address entity and another one for the login entity.

Remember, Java interfaces contain "contract" methods that we implement somewhere else by implementing the interface. Here is the AddressDAO interface. There is If you notice the methods are CREATE, RETRIEVE, UPDATE and DELETE hence CRUD applications. You can also change this to synonyms like create = add; retrieveAll = findAll, etc. You get the idea.

 public interface AddressDAO {  
   public void create(Address newAddress);  
   public List<Address> retrieveAll();  
   public void update(Address address);  
   public void delete(Address address);  
 }  

The LoginDAO interface has exactly the same contents. Just change the Address entities into Login entities. And don't forget to import the List interface from the java.util package.

Now stay tune for part 2....