donderdag 28 november 2013

Hibernate annotated

Introductrion

Setting up a persistence layer with Hibernate is quit easy. Actually it even improved with the annotations. A couple of years ago, when this technique was introduced, there was quite a discussion about the fact if a bean could be self persistent or not. In my personal opinion I dont like self persistent beans. But i do like annotated beans. And I believe there is a difference.

An example

A small version of the hibernate.cfg.xml based on a postgres database:

<?xml version='1.0' encoding='UTF-8'?>
<!DOCTYPE hibernate-configuration PUBLIC
          "-//Hibernate/Hibernate Configuration DTD 3.0//EN"
          "http://hibernate.sourceforge.net/hibernate-configuration-3.0.dtd">
<hibernate-configuration>

  <session-factory>
    <property name="dialect">org.hibernate.dialect.PostgreSQLDialect</property>
    <property name="connection.driver_class">org.postgresql.Driver</property>
    <property name="connection.url">jdbc:postgresql://localhost:5432/mydb</property>
    <property name="connection.username">postgres</property>
    <property name="connection.password">postgres</property>
    <property name="cache.provider_class">org.hibernate.cache.HashtableCacheProvider</property>
    <property name="transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</property>
    <property name="current_session_context_class">thread</property>
    <property name="hibernate.show_sql">false</property>
  </session-factory>
</hibernate-configuration>

In the following example I did not use this but if you have multiple databases you can create more then one configuration file and read them as followed:

SessionFactory sessionFactory = new Configuration()
.configure(<PATH>hibernate.cfg.xml).buildSessionFactory();

an examples of  a annotated hibernate beans:

package com.shops.data.layer.info;



import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.SequenceGenerator;
import javax.persistence.Table;

@Entity
@Table(name = "customers")
public class LoginInfo {

private String username;
private String password;
private long id;

@Column(name = "password")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
@Column(name = "username" )
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
@Id
@Column(name = "id")
long getId() {
return id;
}
void setId(long id) {
this.id = id;
}

}

This bean is actually filled with data coming from a service and is used to create an Criteria.

The next piece of code is an interface that is the template for every class that is going to act as a database controller.
package com.shops.data.layer.session;


public interface ShopsPersistenceController {

/**
* This method adds a customer to the database.
* @param customer contains the data from the customer.
*/
void addData(Object customer, Class annotatedClass);
/**
* This method retreives a customer from the database.
* @param loginInfo contains the login info needed for retreival.
* @param customer the customer retreived from the database.
*/
Object getData(Object selectionData, Class returnTypeClass);
/**
* updates the customer in the database.
* @param customer contains the new data for the database.
*/
void updateData(Object updataData, Class annotatedClass);
/**
* sets the flag deleted on true.
* @param customer the data needed for the database to select the right customer.
*/
void deleteData(Object deleteData, Class annotatedClass);
}

As you can see all the databaseactions as select (get) updated and delete are in place. 

The implementation class:

package com.shops.data.layer.session;

import org.hibernate.SessionFactory;
import org.hibernate.Transaction;
import org.hibernate.cfg.AnnotationConfiguration;
import org.hibernate.cfg.Configuration;
import org.hibernate.classic.Session;

public class ShopsPersistenceControllerImpl implements ShopsPersistenceController{
private SessionFactory sessionFactory;
 
    public ShopsPersistenceControllerImpl(){
    }
/**
* {@inheritDoc}
*/
public void addData(Object addData, Class annotatedClass) {
    Configuration configuration = new AnnotationConfiguration().configure().addAnnotatedClass(annotatedClass);
    sessionFactory = configuration.buildSessionFactory();
    Session session = sessionFactory.openSession();
    session.beginTransaction();
session.save(addData);
close(session);
}

/**
* {@inheritDoc}
*/
public Object getData(Object selectionData, Class returnTypeClass) {
Configuration configuration = new AnnotationConfiguration().configure()
.addAnnotatedClass(returnTypeClass);
sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
SqlSelector selectUserByCredentials = new SelectUserByCredentials(session);
SqlSelector sqlSelector = selectUserByCredentials.whoami(selectionData);
Object info = sqlSelector.getData(selectionData, returnTypeClass);
close(session);
return info;
}

/**
* {@inheritDoc}
*/
public void updateData(Object selectData, Class annotatedClass) {
Configuration configuration = new AnnotationConfiguration().configure().addAnnotatedClass(annotatedClass);
    sessionFactory = configuration.buildSessionFactory();
    Session session = sessionFactory.openSession();
    session = sessionFactory.openSession();
session.beginTransaction().commit();
session.update(selectData.getClass());
close(session);
}

/**
* {@inheritDoc}
*/
public void deleteData(Object deleteData, Class annotatedClass) {
Configuration configuration = new AnnotationConfiguration().configure().addAnnotatedClass(annotatedClass);
    sessionFactory = configuration.buildSessionFactory();
Session session = sessionFactory.openSession();
session.update(deleteData.getClass());
close(session);
}

private void close(Session session){
if(session.getTransaction().isActive()){
Transaction transaction = session.getTransaction();
transaction.commit();
}
session.flush();
session.close();
sessionFactory.close();

}

}

As you can see: the parameters used in all the database action methods have two parameters. One is the bean that needs to handled by the database for example deleteData. the other is annotatedClass. This is the annotated classe that is the class file needed to build the sessionFactory. this way you dont need different methods for diffent beans. 

If you have a closer look in the getData method you find the SqlSelector. This is a separate small class that contains one particular selection. This class has a method called whoami. This method is a part of the chain of responsibility pattern. This way I can chain different selections. This way I keep my contract to the outside world sain. All the services that need this persistence layer talk to it in the same way. They dont have any knowlegde about the query that is executed. This is a good thing. They should be only interested in the results.

The sql selector example:

The interface which is a part of the pattern:

package com.shops.data.layer.session;

public abstract class SqlSelector {

abstract SqlSelector whoami(Object bean);
abstract Object getData(Object selectionData, Class returnTypeClass);
}

The implementing class:

package com.shops.data.layer.session;

import org.hibernate.criterion.Restrictions;

import com.shops.data.layer.info.LoginInfo;
import org.hibernate.classic.Session;
class SelectUserByCredentials extends SqlSelector {
private  Session session;
SelectUserByCredentials(Session session){
this.session = session;
}
/**
         * finds out which bean is needed for what selection.
       **/
SqlSelector whoami(Object bean) {
SqlSelector returnSelector = null; 
if(bean instanceof LoginInfo){
returnSelector = this;
}else{
//TODO create the next sqlSelector.
}
return returnSelector;
}

        /**
         *the actual selection
        **/
Object getData(Object selectionData, Class returnTypeClass) {
LoginInfo loginInfo = (LoginInfo)selectionData;
Object info = session.createCriteria(returnTypeClass)
.add(Restrictions.eq("username", loginInfo.getUsername()))
.add(Restrictions.eq("password", loginInfo.getPassword())).uniqueResult();
return info;
}

}

The created restrictions in the criteria are an equivalent of the where clause in SQL.
the unique result gives back only one result (which is handy when people log on to your applicaton)
The Selector classes will be scoped as package. This for the simple reason that there is no reason to make them visible for the outside world.

Conclusion:

Building a persistence tier with any ORM tool can save you a lot of work. It even can save you more work and miles of code if you take care of your design. 

Try it and Have fun!

woensdag 27 november 2013

pl sql declare and use variable while concat string

Introduction

In this case I did not do anything with java but with sql. The interesting part is that, as a java developer I do not do these things every day. So lets make it memoirable.
I needed to couple two tables by ip adress of the client. But There was no foreign key to deal with. The first table had all the parts of the ip adress as numbers addr1 would be 127 addr2 would be 0 addr3 would be 0 and addr4 would be 7. In the other table the whole ip adress would appear like '127.0.0.1'. The whole selection would have a where clause by name from another table.

Solving the problem

So the first thing I needed to do was declare a variable and add the value of the ips to it with a selection over two tables based on the name of the compagny that looks like:

set serveroutput on --makes it printable
declare
  v_line varchar2(40); -- declares the var v_line
  begin
    select TO_CHAR(addr1)|| '.' || TO_CHAR(addr2) || '.' || TO_CHAR(addr3) || '.' || TO_CHAR(addr4)into v_line from ip_adress join comp on ip_adress.comp_id = comp.id where comp.name = 'my compangy'; -- TO-CHAR converts the number into a string
   --the || are the concat commands.
 dbms_output.put_line (v_line) -- prints the ipadress;
  end;
   / -- this is like an end sign dont forget it.

So now we have variable filled with a selection from the database.
In the following line You can do  a selection based on the variable:

 select * from STAT_HOURLY_SESSIONS_COUNT where STAT_HOURLY_SESSIONS_COUNT.machine = :v_line;  -- dont forget the : before the variable.

Declare the variable, and execute the query in one run.
Conclusion

If you want to build a database read the normalisation rules by Codd. Doing it like this is not improving the simpleness and performance of your database actions.

Have fun.

maandag 11 november 2013

check webresource status

   
Introduction:

Sometimes you want to know if a service is responding correctly before you give it the actual task.
With a small piece of code you can test if the response you get is an apropriate one.

The imports are from the :

<dependency>
<groupId>commons-httpclient</groupId>
<artifactId>commons-httpclient</artifactId>
<version>3.1</version>
</dependency>

The example:

boolean isUp = false;
HttpClient client = new HttpClient();
               //********************************************************
//Optional for https sessions. You can run it through a trusted proxy
        // to get the certificates.
//client.getHostConfiguration().setProxy("MyProxy", MyProxyPort);
                //********************************************************
     GetMethod method = new GetMethod("http://www.google.nl/");
     try{
         client.executeMethod(method);
         if(method.getStatusCode()==200){
                     isUp = true;
                 }


     }catch(Exception e) {
         System.err.println(e);
     }finally {
         method.releaseConnection();
     }
return isUp;

Conclusion:

It is quiet easy to check before you send your query or data to a url to check if it will respond correctly.
So have fun!