Sunday, December 6, 2009

Performance tuning with Hibernate – Understanding fetching strategies


Sky is the limit when it comes to improve the performance of a hibernate based application. But before jumping to using second level cache, terrcotta etc., there are a few things we need to look at first. Below are a few lessons learned from experience →

Choose the right fetching strategy:

It is very important to understand how hibernate issues SQLs to the DB for different fetching strategies. If hibernate issues too many queries to the database, it can cause significant performance degradation. Let's take an example of department and employee relationship.

We have one to many relationship between dept and employee. Below is how we can translate this association in hibernate →

@Entity

public class Dept implements java.io.Serilizable{


….

….

@OneToMany

private Collection employees;

public Collection getEmployees{

return employees;

}

public void setEmployees(Collection emps{

this.employees = emps;

}


}


Now, lets say we want to get the name of the emplyees in each dept. We will do something like →


Collection depts = (Collection) entityManager.createQuery(“select dept from Dept dept”).getResultSet();

for(Dept dept:depts){

for(Employee emp: dept.getEmployees(){

//process employee

}

}

Looks simple and straightforward. But, if we have N depts, the above example will issue N+1 SQL statements to the database.

One SQL to feth all the departments:

select * from department;

N SQLs to fetch emplyees for N departments.

select * from emplyee where deptid=

….

select * from emplyee where deptid=


Now, that's a lot of calls to the DB. This is what is typically known as N+1 selection problem. There are two ways avoid this.

  • Fetch data in batches

    You define a batch size in the relationship mapping as

    @OneToMany

    @batch-size=10

    The above will fetch employees in batches of 10 departments as →

    select *from employees deptid in (1st dept-id, ….,10th dept-id)

  • Use subselect

@OneToMany

    @subselect

  • This will issue only two SQL statements. It will use the original query (that was used to fetch the dept )as the sub query to get all employees.

    select *from employees deptid in (select id from department)


For ManyToOne and OneToOne mapping, the default fetching strategy is ESGER. Change it to LAZY if you do not want the associated object to be loaded with the main object as hibernate will issue an additional SQL to fetch the related object. If you need the related object, user EAGER-JOIN strategy so that hibernate issues one outer-join statement to retrieve two objects as opposed to two different queries. Remember to do due diligence before using EAGE-FETCH though, if hibernate fetches too many unnecessary data there is a performance overhead due to network traffic, too many objects in memory and the time hibernate takes to translate these data to objects.

The other thing to remember is to always use the same instance of entity manager so that objects can be retrieved from the cache. Hibernate cache is maintained with the entitymanager istance. If you use different instances of entityManager, the same object will be fetched from DB repeatedly.

Bottom line is always turn on the show-sql property to “true” in the development environment and monitor the SQL statements issued by hibernate. I can assure you from my experience that you will get great performance benefit just by optimizing the SQL calls.

Friday, May 29, 2009

Testing webservice- Simplified with SoapUI

Testing webservice during development time can be tedious. Thanks to SoapUI, not anymore. It’s a free tool (I have not used the pro version, very happy with the free version itself) where you can create a SOAP request, send it to your webservice and see the response. The steps are very simple ->
  • Import the WSDL
  • Create your test suite
  • Drag the requests to the test suite
  • Enter the input values in the request (in XML format)
  • Execute the test case and you will see the response in the XML format

During development time, I found it very convenient to use for unit testing. Once you exposed an API, export the new WSDL and test is for all possible inputs. Once you create the test cases, you can save it with the SoapUI project to use later.

You can use SoapUI for functional testing as well by combining different requests in the same test case. You can also write your test client in Groovy script.

I think it is a great tool for webservice developers for unit testing and recommend you to try if you have not already.

Tuesday, May 26, 2009

Paired Programming - Two people must share the same goal

The technique is simple. Two programmers work on the same machine. One person typing the code (called driver) while the other reviewing the code (called navigator). They keep switching role as frequently as every hour.

What are the benefits you ask?
Well, if more than one developer is aware of the code, the project is less dependent on any single person. Besides, the code is better as two persons have put thoughts about the implementation and reviewed each other’s work. Also, skills and knowledge is transferred between each other without any specific training sessions.

It all sounds good theoretically, but my personal experience has been a little less cushy with implementing this technique in coding. Below is one of the main issues I found in one of the projects that I worked with.

Paired Programming does not work if two people do not share the same goal. John and Tim were paired to code a piece of the software. During the coding, John was also assigned with another important task that only he could perform. After this, I noticed that John was assuming more of a navigator role while Tim is the driver most of the time. Also, Tim noticed a significant decrease in participation from John .He pretty much okayed whatever Tim coded. When I talked to John about it later, he told me that his mind is mostly preoccupied with the other task that he is assigned to. Since the other task is only his responsibility, he can not take any chance for that to fail. He thinks Tim can manage the coding part.
In the above scenario, the whole purpose of paired programming is defeated as it is as good as Tim coding the software alone. The result could be worse as the code will not be reviewed by another developer as the perception is that John has already reviewed it. We ended up in this situation because John and Tim did not share the same goal. Tim’s goal was still coding while John was more focused on the task he was assigned to.

Tuesday, May 19, 2009

Web Application Security & SQL-Injection

SQL Injection is a technique to inject SQL query or command as an input to the application through web pages. The intent is to make the application run some malicious SQL queries.

Below are some of the threats from SQL Injection->

Unauthorized Access:
Suppose a developer takes the username and password as inputs from the web page and executes the following query to authenticate/authorize a user.
sqlQuery = “SELECT * from users WHERE username=’”+strUsrName+”’ AND password= ‘”+strPassword+”’”;
If the code is determining the validity of the user by checling if any record returned from the above statement, below is a catch.

A malicious user can pass “blah’ or 1=1” for password field and the code above will give the user access to the application. How? The SQL query above will now read ->
SELECT username from users WHERE username=’does nor matter’ AND
password= ‘blah’ OR 1=1

Because of the "OR 1=1" condition, the query will return all the records in the users table.

Adding a new User:

Now, in the same example pass “blah’; INSERT into users (“username”,password”,”email”) values (“JohnDoe”,”hackedit”,johnDoe@fakeemail.com)” as an input to the password field.
The SQL above will read ->
SELECT * from users WHERE username=’does nor matter’ AND
password= ‘blah’; INSERT into users (“username”,password”,”email”) values (“JohnDoe”,”hackedit”,
johnDoe@fakeemail.com)
The login might fail, but will create a new user account and the hacker can use it to access your application going forward.

Changing DB Schema:
If the DB is not read-only, we have a more serious threat.
Now, in the same example pass “blah’; drop table users;” as an input to the password field.
The SQL above will read ->
SELECT * from users WHERE username=’does nor matter’ AND
password= ‘blah’; drop table users;
And that’s it, the user table will be dropped and nobody can access the application.

Preventing SQL-Injection:

SQL Injection can be prevented by using parametrized SQLs.
The above code can be written as below and can be protected from SQL-Injection.

sqlQuery = “SELECT username from users WHERE username=? AND password= ?”
PreparedStatement pStmt = con.prepareStatement(sqlQuery);
pStmt.setString(1,strUsrName);
pStmt.setString(1,strPassword);
ResultSet rs= pStmt.executeQuery()

Variables passed as arguments to PreparedStatement are escaped by JDBC drive.

Monday, May 18, 2009

iPhone 3.0 - No backward compatibility

Apple declared that all the applications submitted to appstore must be complianed with iPhone3.0 OS. That means all you iPhone application needs to be upgraded.
New application developers, make sure your app is tested with the new OS and also works with the old OS (for people who do not switch to the new OS).

Thursday, May 14, 2009

Implementing Application Security with SEAM

Seam helps you secure your application without spending too much time in the details. Seam’s security model is based on a role based system. Seam leverages the Drools rule engine to support contextual, role-based permissions. The fact that we don’t have to write a single line of XML is very welcoming to developers who have used other java security framework.
Authentication:
The authentication features are built upon JAAS, but Seam offers simplified methods of authentication that hides the complexity of JAAS.
Steps for implementing authentication:
1. Switch authentication through Configuration:
You have to tell Seam which method handles the authentication logic. The authentication method ->
  • Must take no argument.
  • Must return a Boolean indicating if credential could be verified.
  • Must be accessible via the EL.

The authentication method can have any name and can reside in any class. The authentication routine is activated through Seam’s Identity component. You can bind the authenticating method to Identity component by adding the following line in components.xml

The above line means the authenticate method in the authenticator component will be used for authentication.
2. Write an authentication method to verify user credential

@Name("authenticator")
public class Authenticator {
@In Identity identity;
@In
private EntityManager entityManager;
public boolean authenticate() {
String username = identity.getUsername();
String PASSWORD = identity. getPassword ();
try {
User user = (User)entityManager.createQuery("select u from User u where u.username like :username and u.password like :password ")
.setParameter("username", username)
.setParameter("password ", password)
.getSingleResult();
if(null != user.getRoles()){
for(Role role: user.getRoles(){
identity.addRole(role.getName());} }
} catch (NoResultException ex) {
log.error("Invalid username/password.", ex);
return false;}
return true;
}

In the above example both User and Role are application specific entity beans. The username and password in the identity component are used to find a matching User entity in DB through entityManager. Once the user is validated, the roles assigned to the user are added to the identity component.

3. Create a login form.
The login form boils down to binding the username and password properties from the identity component to the username and password fields on the login form. After the properties are set, the login method in identity component is called to authenticate the user.
Below is an example of simple login form->

<div> <h:outputLabel for="username">Username</ h:outputLabel> <h:inputText id=" username value="#{identity.username}"/> </div>
<div> <h:outputLabel for="password">Password</ h:outputLabel> <h:inputSecret id="password" value="#{identity.password}"/> </div>
<div> <h:commandButton value="Login" action="#{identity.login}"/> </div>

Authorization:
Authorization is about checking if a user is permitted to access a restricted resource or permitted to perform a restricted action.
Role based authorization:
Seam component are secured either in the class level or method level with @Restrict annotation.
Class Level Restriction:
Example: Restrict the component to only users with Admin role

@Restrict(“#{s:hasRole(‘admin’)}”)
Public class AdminAction{
Public void add(){
}
Public void delete(){
}
}

In the above example the user need to have admin role to perform any action under AdminAction class.

Method Level Restriction:
Example: Only Super user can “delete” and Admin user can “add”.

@Restrict(“#{s:hasRole(‘admin’)}”)
Public class AddDeleteAction{
@Restrict(“#{s:hasRole(‘admin)}”)
Public void add(){
}
@Restrict(“#{s:hasRole(‘super)}”)
Public void delete(){
}
}

In the above example the user need to have admin role to perform “add” operation and super user access to perform “delete” operation.

Note: If “Restrict” is applied both at class level and method level, method level restriction takes precedence.

Rule based Authorization
Seam uses JBoss Rules to provide rule bases authorization. The advantage of rule bases authorization is a centralized location for business logics and user permissions.

Steps for Rule based authorization:
1. Configure RuleBase Component in components.xml.

/META-INF/security-rules.drl


2. Write Security rules file
Create a security-rules.drl in the /META-INF directory of the application’s jar file. The file should look like below->


package RuleCheck;
import org.jboss.seam.security.PermissionCheck;
import org.jboss.seam.security.Role;

rule CanModifyRole
when
c: PermissionCheck(name == "Role", action == "update")
Role(name == "admin")
then
c.grant()
end;

The above rule states that only admin user can modify roles of other User. In the line
c: PermissionCheck(name == "Role", action == "update")
“name==’Role’” specifies the entity/component for which permission is granted and “action=’update’” specifies the specific action the user is granted access to.