Friday, February 14, 2014

Defining Persistent Objects

The persistent objects can be defined either in xml file, or using annotation. The annotation method is easy to define simple relationship while defining in xml file provides more flexibility.

This article demonstrates, rather shortcut, how we can create persistence objects:

//Base Class
@MappedSuperclass
public abstract class BaseClass implements Interface{
@Id
@Column(name = "id")
@GeneratedValue
@Override
private int id

@Transient
private String unwantedField;

public int getId(){
    return id;
}

public void setId(int id){
    this.id=id;
}
}

//Child Class
@Entity
@Table(name = "table_name")
public class ChildClass extends BaseClass{

@Column(name = "user_name")
private String useName;

@OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, fetch = FetchType.EAGER)
@JoinColumn(name = "id")
@Override
private List comments;
}


//Associated class
@Entity
@Table(name = "another_table")
public class AnotherClass {
@Id
@Column(name = "comment_id") //this can not be "id", because "id" is referenced from ChildClass
@GeneratedValue
private int id;
@ManyToOne
@JoinColumn(name = "id") //this id is child class identifier column
private ChildClass child;

}

In above example, we implemented one to many relationship from ChildClass to AnotherClass instances.(Getters and setters not shown above). So, the "id" in "another_table" is foreign key from the table "table_name".

[Note: Annotations should be either at properties definition or at getters(CAN'T  be mixed).]





Accessing Persistent Objects

In the previous article, I have discussed how to create session instance. This article demonstrates how session object can be used to access persistence objects, insert, update or remove objects.
[Assumption: we have session object, and we have to close transaction and session after we complete operation]

1) Insert, Update or Delete persistence object

  session.saveorUpdate(object);
  session.delete(object);

2) Retrieve a collection of data
   i) If you want all persistent objects
       //using hibernate query
       List list=session.createQuery(HQL).list();
       //using sql 
       List list=session.createSQLquery(SQL).list();//gets raw
       List list=session.createSQLquery(SQL).addEntity(className).list();//entity objects

   ii) If you want selected object only (similar to WHERE clause in SQL)
 
     String HQL="SELECT * FROM ENTITY entity WHERE entity.fieldName=:fieldname";
     session.createQuery(HQL).setString(fieldname, value).list();
 
     For SQL, we create the sql query to get the list.      

    Criteria is more elegant for selection.
   
      Criteria criteria = session.createCriteria(className);
       criteria.addOrder(Order.desc(fieldName));
       criteria.add(Restrictions.ge(fieldName, value));
       criteria.add(Restrictions.le(fieldName, value));
      criteria.setMaxResults(limit);
      
      // Also define union and intersection
       Disjunction disjunction = Restrictions.disjunction();
       disjunction.add(Restrictions.eq(fieldName, "#BLABLA#"));
       criteria.add(disjunction);      
       Conjunction conjunction=Restrictions.conjunciton();
       conjunction.add(Restrictions.eq(fieldName, "#BLABLA#"));
       criteria.add(conjunction);    

        criteria.setFetchMode("whatever", FetchMode.SELECT);

     List objects= criteria.list(); 

3) Retrieve specific object

We have to note here that all persistence objects have their own id. So,  with the id, we can get object

 Object object=session.get(className, id);

Hibernate Basics

Recently, I faced a lot of problem implementing persistence of objects with the database using Hibenate persistence API. If we know exactly, its very easy and straight task implement persistence on the objects with database, otherwise, we might get very peculiar problems where it takes a lot of time to get out of it.

In this article, I will present my experience creating persistence objects using PostgreSql database. I will start from beginning so that you can directly use the source code in your implementation.

1) Get Data Source
Use the following method to get datasource. We use this later when creating properites.
private DataSource getDataSource(String host, String database, String userName, String password) {
PoolProperties poolProps = new PoolProperties();
poolProps.setUrl("jdbc:postgresql://" + host + "/" + database);
poolProps.setDriverClassName("org.postgresql.Driver");
poolProps.setUsername(userName);
poolProps.setPassword(password);

poolProps.setJmxEnabled(true);
poolProps.setTestWhileIdle(false);
poolProps.setTestOnBorrow(true);
poolProps.setValidationQuery("SELECT 1");
poolProps.setTestOnReturn(false);
poolProps.setValidationInterval(30000);
poolProps.setTimeBetweenEvictionRunsMillis(30000);

poolProps.setMaxActive(75);
poolProps.setMaxIdle(25);
poolProps.setInitialSize(3);
poolProps.setMaxWait(10000);
poolProps.setRemoveAbandonedTimeout(60);
poolProps.setMinEvictableIdleTimeMillis(30000);
poolProps.setMinIdle(10);

poolProps.setLogAbandoned(true);
poolProps.setRemoveAbandoned(true);

poolProps.setJdbcInterceptors("org.apache.tomcat.jdbc.pool.interceptor.ConnectionState;" + "org.apache.tomcat.jdbc.pool.interceptor.StatementFinalizer");

DataSource dataSource = new DataSource();
dataSource.setPoolProperties(poolProps);

return dataSource;
}


2) Create properties object

Properties props = new Properties();
props.put("hibernate.connection.datasource", getDataSource(hostname, database, username, password));
props.put("hibernate.cglib.use_reflection_optimizer", true);
props.put("hibernate.show_sql", false);
props.put("hibernate.hbm2ddl.auto", "update");
props.put("transaction.factory_class", "org.hibernate.transaction.JDBCTransactionFactory");
props.put("hibernate.jdbc.batch_size", batchSize);
props.put("hibernate.default_batch_fetch_size", fetchSize);
props.put("hibernate.dialect", "org.hibernate.dialect.PostgreSQLDialect");


3) Create Configuration

Configuration config = new Configuration();
config.setProperties(props);
//class registration
config.addAnnotatedClass(className);

If we have to register all classes in the specified package, then we have to get all classes inside the package.

4) Create session factory

ServiceRegistry serviceRegistry = new ServiceRegistryBuilder().applySettings(props).buildServiceRegistry();
SessionFactory sessionFactory = config.buildSessionFactory(serviceRegistry);

5) We have to get session for persistent objects, so we get this by:

Session session = sessionFactory.openSession();
session.setFlushMode(FlushMode.COMMIT);

6) While executing query

Session session0sessionFactory.openSession();
Transaction trans=session.beginTransaction();
session.delete(object);
trans.commit();
session.close();


Creating persistence objects will remove the bother of thinking the database structure and tables. We just care about objects, and the back end database operations are carried out by hibernate API itself.


Automating Jobs in Linux System (Crontab)

We install applications and services in the Ubuntu system and they go on running all the time. So, it is not guaranteed that they run perfectly. Even, some services generate huge log files, or some services go on consuming more and more memory, finally, making the system crash with memory leak. So, to minimize those problems, we implement the auto-restart in the system.

Since, we have different system configuration (such as services, hardware and memory), the way we define auto-restart is different for different system, so we don't make it built-in image characteristics.

The settings of auto-restarting of server is quite easy task if we are familiar with Linux's crontab application.

Edit

crontab

We can define the automated tasks using crontab command from the terminal as below:
crontab -e
Then we have to select the preferred editor, after that we go into the editor where we define the tasks to run at specified time. We have to add a line for each task in the following format:
minute hour day_of_month month day_of_week command
Note: every users have different crontab file generated in /var/spool/cron/crontabs with the name of the user.
So, that if enough for theory. Now, if we add the following line
20 01 * * 1 sudo reboot
Then it restarts the system every Sunday at 01:20 am.(The user should have super user privilage to restart the system.)
We can change the values according to our requirements.

Edit

/etc/crontab

We can define user wise cron tasks by editing /etc/crontab file. The format is same as above, only we have to provide the user name can execute the defined task, for example:
20 01 * * 1 frietec sudo reboot
So, the user frietec reboots the system every Sunday at 01:20 am.

[Note: the command provided should be executable by the provided user, otherwise, nothing happens.]

If you look into the file /etc/crontab file, you will notice there is already some automated tasks in the folders /etc/cron.hourly /etc/cron.daily /etc/cron.weekly /etc/cron.monthly defined in the file.  So, an alternative will be keep the task(script) in the specified folder to execute at the define time in /etc/crontab file.

clear log files

Log files in linux system are located under /var/log directory. And the long time running system, in case there is some problem, will grow log files size. So, to prevent the system from crashing, we have to implement the mechanism to clear log files.
A simple method to clear log files is to place following line in the crontab job:
0 11 * * 1 find /var/log -type f -delete
This line will find all log files inside /var/log directory and deletes.
The above command can be executed by root user only, so we keep this in root crontab.