Wednesday, 19 September 2012

Selecting duplicates in a database table

Selecting duplicates in a database table can be accomplished in various ways and all these approaches involve various trade-offs with respect to efficiency and speed but before we start examining some of these approaches we need a table with duplicates so here is one. The Primary Key in this table is the ID and the Emp_Id is meant to be Unique and will be used for filtering duplicates.


Listing the number of times each record occurs with duplicate rows listed once.

(1) select *, count(*) from employee group by Emp_Id;



Listing the number of times each record occurs with a listing of the first row in the group.

(2) select *, count(*) from employee group by Emp_Id having count(*) > 1;



To list all duplicate rows, the following query would work;


(3) select   a.* from
    employee as a
inner join
    (select Emp_Id
     from employee
     group by Emp_Id
     having count(*) = 2) as b
  on a.Emp_Id = b.Emp_Id;

Now our table has a Tele_No column and some of these numbers are incorrect

Selecting the duplicates using a self-join.

In this case, we need to select all records that have the same Emp_Id but a different Tele_No. We can use a simple self-join with the Tele_No and the column as the distinguishing key to separate our records.
Option 1

(4) select e1.* from employee e1, employee e2 where e1.Emp_Id = e2.Emp_Id and e1.Tele_No != e2.Tele_No order by e1.Id asc;




The exact same result could also be obtained with a sub-query as follows:
Option 2

(5) select e1.* from
employee e1 where e1.Emp_Id IN (
select e2.Emp_Id from employee e2
where e1.Emp_Id = e2.Emp_Id
and e1.Tele_No != e2.Tele_No
) 
order by e1.Id asc;

In Option 1 & 2, we have the condition e1.Tele_No != e2.Tele_No that prevents us from getting a cartesian product of the records. If such a condition is not available then just use the Primary Key column as follows:


(6) select e1.* from
employee e1 where e1.Emp_Id IN (
select e2.Emp_Id from employee e2
where e1.Emp_Id = e2.Emp_Id
and e1.ID <> e2.ID
)
order by e1.Id asc;


If you are wondering whether a join or a sub-query would work best, it would ofcourse depend upon your query optimizer and the size of your tables but generally Joins are the way to go.

So, we have 6 records where the Emp_Id are the same but the Tele_Nos are different. To view these records in a tabular format we could modify (6) as follows.

(7) select e1.ID, e1.Tele_No,e2.ID, e2.Tele_no
from
employee e1, employee e2
         where e1.Emp_Id = e2.Emp_Id
               and e1.Tele_No != e2.Tele_No
               and e1.Id < e2.id
        order by e1.Id asc;



The change in the condition comparing the Primary Keys in the query above e1.Id < e2.id prevents a cartesian product.

Sunday, 16 September 2012

Setting up an Image Gallery in Joomla

Most Joomla based sites end up requiring an image gallery of some sort and while there are a variety of  options available, you are liable to run into trouble with Javascript conflicts between the Javascript version or library of your Image Gallery plug-in with the other Javascript libraries loaded by the other plug-ins or the template. One option is ofcourse to hack the php template and debugging the Javascript conflicts using a browser based debugger which could be a tricky as well as tedious exercise.
The other and more staright forward approach is to use a non-Javascript based image gallery plug-in. One such plug-in is the css-gallery plugin. The plug-in is easy to install and has a simple configurable interface which is well documented. It is also  possible to add captions and link to the gallery images. It took 5 minutes to set up the image gallery for the St John English School website. An example of the css-image gallery in action can be viewed here. 

Sunday, 26 August 2012

Setting up HIbernate Search on a Maven build

Hibernate Search is an interesting companion of the Hibernate core components. Since most applications with a public facing view invariably require, a search capability, Hibernate Search presents itself as an east to configure and implement, search tool that fits in well with the Hibernate ORM framework, Under the covers, Hibernate Search uses the Apache Lucene search engine and it is possible to write search queries directly targeting Lucene.Since Hibernate Search is annotation driven, it is preferable to have an annotation based implementation of Hibernate Core of your data model.

The following dependency definitions in your pom.xml will add the required Hibernate Search jars to your project.


org.hibernate
hibernate-search 
3.4.2.Final 

Add the following property settings to your Hibernate.cfg.xml file.



org.hibernate.search.store.FSDirectoryProvider


lucene

These setting will direct Hibernate Search to create the Index base and store it on the File System in a directory named Lucene.

This is all you need to add Hibernate Search to your current project setup. Now all you need is to annotate the fields in your domain model that need to be searchable,

The key annotations are as follows:

@Indexed
@Table(name = "User")
public class User implements Serializable
{

@Field(index=Index.TOKENIZED, store=Store.NO)
private String userName;
}

The @Indexed annotation tells Search to Index this particular table.
The @Field(index=Index.TOKENIZED, store=Store.NO) annotations on the attribute definition tells Search to tokenize the field using the default analyzer. The store annotation tells Hibernate not to store the data with the index and this is the default behaviour. Storing data within the index is required is using a Projection.

You can read more about setting up Hibernate Search at Getting Started

Sunday, 19 August 2012

Managing PermGen and Heap allocations in Tomcat7

If you are developing a web-application that runs on Tomcat 7, it is highly likely that you will encounter a PermGen space error on Tomcat which happens when you deploy and undeploy the application several times and there is a memory leak. There could be several reasons for a memory leak and they could stem from loading third-party jars such as JDBC drivers and logger jars from within the web-application lib. To overcome some of these potential issues, it is best to load them directly into Tomcat lib and let Tomcat the Driver Manager take care of de-registering them when not in use.

While the best approach to dealing with this problems and other memory related problems is debugging the cause of the memory leak and fixing it, there are times when tuning the JVM parameters can alleviate the cause and improve performance of the application to a certain extent.

Before diving into the tuning the JVM parameters, it is important to understand how JVM organises its memory space and what is the difference between heap and permgen space and how they are used. This article gives a very good overview of the JVM memory layout.  To summarise the difference between the two, the permgen space is used to store classes loaded by the class loader, primitives,any static classes and other JVM related data. On the other hand, the heap space is mainly used to store objects created by the application. It is further divided as explained here into Eden, Survivor and Tenured Gen space.

It is also important to note that since Java 1.6 update 16, there have been some major changes to the process used to compute heap size in 32 bit and 64 bit JVMs and in client / server mode.

Having understood the basics of JVM memory organisation, we can look at tuning Tomcat's memory allocation for its heap and permgen. While there are several parameters that can be used for tuning the JVM, this post is just going to describe the minimum and maximum parameters for specifying the heap and the permgen space. The location of where to specify these parameters and their values depends on your machine specification (operating system, memory size, 32 bit or 64 bit) and how you invoke Tomcat.

Deciding on the actual values of the parameters should be taken after monitoring the JVM using some tools such as jVisualVM. The values given below are sample values that worked in my particular case.

Case 1: Tomcat is invoked from within Eclipse on a 32 bit machine.
Specs : Tomcat 7.0.28, Eclipse Juno, Sun Java 1.6.30, Windows 7.0

The parameters should be specified in Server Launch Configuration -> Open Launch Configuration -> Edit Launch Configuration Properties ->Arguments
Tomcat Launch Configuration in Eclipse
The detailed steps are available here.

Case 2: Tomcat is invoked via its start up script on a 32 bit virtual machine.
Specs : Tomcat 7.0.28, Sun Java 1.6.30, Ubuntu 12.04

Create a setenv.sh file and add the following one line in it.

export JAVA_OPTS="-Dfile.encoding=UTF-8 -server -Xms128m -Xmx256m -XX:MaxPermSize=128m -XX:+DisableExplicitGC"

Transfer this file to your Tomcat/bin directory and re-start Tomcat.

There are a number of ways of verifying that the JVM parameters were applied to Tomcat. The easiest way on Ubuntu is : ps -ef | grep tomcat

You should see something similar to the line below:

john     17841     1  5 15:23 pts/0    00:00:09 /usr/bin/java -


Djava.util.logging.config.file=/usr/local/apache-tomcat/conf/logging.properties -Xms128m -Xmx256m -XX:MaxPermSize=128m -XX:+DisableExplicitGC -
Djava.endorsed.dirs=/usr/local/apache-tomcat/endorsed -classpath /usr/local/apache-tomcat/bin/bootstrap.jar:/usr/local/apache-tomcat/bin/tomcat-juli.jar -Dcatalina.base=/usr/local/apache-tomcat -Dcatalina.home=/usr/local/apache-tomcat -Djava.io.tmpdir=/usr/local/apache-tomcat/temp org.apache.catalina.startup.Bootstrap start



With respect to parameter values for the heap, it is important to note that :

(Managed Heap + native heap + (thread stack size * number of threads)) cannot exceed 2GB on 32bit x86 Windows or Linux systems (ref)


2GB is a theoretical limit. Since the heap requires contiguous memory space, it might be hard to push the heap beyond 1.4GB on a 32 bit Windows machine.

A final comment.
The JVM is an intelligent software and has several inbuilt processes built into it that work to optimize its performance. Attempting to tune the JVM may not always result in a performance improvement. Tuning the JVM is dependent on the machine specification, the design decisions taken behind the architecture of the web-application it is hosting, the number of applications hosted by the JVM and when all else fails, Trial and Error.