Tuesday, September 21, 2010

Gmail or Google Apps as Liferay SMTP Server

Good thing of this approach is you don't need restart compare to setting inside ROOT.xml or portal-ext.properties

Go to

 Control Panel --> Server Administration --> Mail 
and enter these values 














Note : If you don't see emails coming, enable your pop of your gmail account.


Friday, September 10, 2010

JPA Performance settings Explained

Lets consider this simple Entity, Ignore @SecondaryTables and other annotations if you are not familiar with just focus on @Basic, @OneToOne, @OneToMany annotations and get ready to answer these questions.

@Entity
@SecondaryTables({
    @SecondaryTable(name="Employee_Comments")
})
public class Employee implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    private Long id;
    @Column(name = "name")
    private String name;
    @Basic(fetch = FetchType.LAZY)
    @Column(name = "comments", table = "Employee_Comments")
    private String comments;
    @OneToMany
    private List tags = new ArrayList();

    @OneToOne(fetch=FetchType.LAZY)
    private Address address;
..

}

What happens when we load the above entity using em.find or by executing some select query ?

  1.   "comments" is Eagerly loaded
  2.   "comments" is Lazily loaded
  3.   "address" is Eagerly loaded
  4.   "address is Lazily loaded
  5.   "tags" is Eagerly loaded
  6.   "tags" is Lazily loaded
You might have guessed 2, 4 and 6 or 1, 3, 6 though neither of these are correct.

Since

@Basic(fetch = FetchType.LAZY)
@OneToOne(fetch=FetchType.LAZY)
@OneToMany(fetch=FetchType.LAZY)


 Are just "hints" to the JPA provider and its not mandatory for JPA provider to implement them, So their is no quarantee that these objects when loaded will be lazily loaded.

Conclusion : Entities heavily using above annotations and also if we load and them in bulk could seriously cause performance bottlenecks, however there are nice ways of loading entities with trim data using "Contructor" Queries. which will be topic of my next thread.

Reference JPA Specs.

http://jcp.org/aboutJava/communityprocess/final/jsr317/index.html
JPA 2.0 Specification document Page 364

"FetchType fetch (Optional) Whether the value of the field or property
should be lazily loaded or must be eagerly fetched. The
EAGER strategy is a requirement on the persistence provider
runtime that the value must be eagerly fetched. The
LAZY strategy is a hint to the persistence provider runtime.
EAGER "

@OneToOne(fetch=FetchType.LAZY)
JPA 2.0 Specification document Page 402
Also have the same comment 


@OneToMany(fetch=FetchType.LAZY)
JPA 2.0 Specification document Page 400Also have the same comment 



Wednesday, September 8, 2010

Reading RSS Feed in Java (3 llines of code) Explained

Rome is a very simple Java API for reading RSS Feeds and is available under Apache License 2.0

Rome Home Page
https://rome.dev.java.net/

If you are a maven user just add this dependency

        <dependency>
            <groupId>rome</groupId>
            <artifactId>rome</artifactId>
            <version>1.0RC2</version>
        </dependency>

if you are using ant
  1. Add Rome jar from https://rome.dev.java.net/dist/rome-1.0.jar
  2. Add JDOM jar from http://www.jdom.org/dist/binary/archive/jdom-1.0.zip

And here is the code to pull feeds, 

import java.net.URL;
import java.util.List;
import com.sun.syndication.feed.synd.SyndEntry;
import com.sun.syndication.feed.synd.SyndFeed;
import com.sun.syndication.io.SyndFeedInput;
import com.sun.syndication.io.XmlReader;

public class App {
    public static void main(String[] args) throws Exception {
        String url = "http://rss.cnn.com/rss/cnn_topstories.rss";
        URL feedUrl = new URL(url);
        SyndFeedInput input = new SyndFeedInput();
        SyndFeed feed = input.build(new XmlReader(feedUrl));
        for (SyndEntry entry : (List<SyndEntry>)feed.getEntries()) {
            System.out.println(entry.getTitle());
        }
    }
}

Checkout SyndEntry  API doc

It was that simple just instantiating SyndFeedInput and SyndFeed

Tuesday, September 7, 2010

JPA 2 new feature @ElementCollection explained

@ElementCollection is new annotation introduced in JPA 2.0, This will help us get rid of One-Many and Many-One shitty syntax.

Example 1: Stores list of Strings in an Entity

@Entity
public class Users implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ElementCollection
    private List<String> certifications = new ArrayList<String>();

    public Long getId() {
        return id;
    }

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

    public List
<String> getCertifications() {
        return certifications;
    }

    public void setCertifications(List
<String> certifications) {
        this.certifications = certifications;
    }

..
}

        Users u = new Users();
        u.getCertifications().add("Sun Certified Java Programmer");
        em.persist(u);

Generated Tables

   Users
   Column --> ID
    Row             1

Users_CERTIFICATIONS
  Column  Users_ID      CERTIFICATIONS
  Row           1                 Sun Certified Java Programmer

 @ElementCollection rules
  1.    This annotation was introduced to map basic and embedded type objects
  2.    You can use any collection of type Collection, List, Set, Map
  3.    Its easy to override default values for generated Tables and Columns
  4.    JPA 1.0 only supported collection holding entity types using (@ManyToOne, @OneToMany) annotations
Lets quickly look at code snippet for Embedded object based collection


@Embeddable
public class Certification {

    @Column(name = "name")
    private String name;
    @Temporal(TemporalType.DATE)
    @Column(name = "issue_date")
    private Date issueDate;

    public Date getIssueDate() {
        return issueDate;
    }

    public void setIssueDate(Date issueDate) {
        this.issueDate = issueDate;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }
}


@Entity
public class Users implements Serializable {

    private static final long serialVersionUID = 1L;
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;
    @ElementCollection
    @CollectionTable(name = "Certification", joinColumns = {@JoinColumn(name="user_id")})
    private List<Certification> certifications = new ArrayList<Certification>();

   
    public Long getId() {
        return id;
    }

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

    public List
<Certification> getCertifications() {
        return certifications;
    }

    public void setCertifications(List
<Certification> certifications) {
        this.certifications = certifications;
    }
..

}


        Users u = new Users();
        Certification c = new Certification();
        c.setName("Sun Certified Java Programmer");
        c.setIssueDate(new Date());
        u.getCertifications().add(c);
        em.persist(u);

Resulted Table structure

Table --> Users
   Column --> ID
    Row             1

Table --> Users_Certification
  Column  user_id      name                                                   Issue_Date                         
  Row           1                 Sun Certified Java Programmer        2010-09-05

Map based Collection is a rich area it needs a seperate article to describe it some detail.

Liferay DWR Session and Security made easy

In my previous article I discussed about using DWR inside Liferay Portlets, I wasn't happy with security this model provides. First lets have a look at what I proposed

ThemeDisplay themeDisplay = (ThemeDisplay)portletRequest.getAttribute(WebKeys.THEME_DISPLAY);
        portletRequest.getPortletSession().setAttribute("THEME_DISPLAY", themeDisplay, PortletSession.APPLICATION_SCOPE);

I was executing the above code inside my portlet's doView() and this puts themeDisplay or remoteUser object into portlet session's application scope, that means my DWR classes access the object like this

    @RemoteMethod
    public String echo(String msg, HttpSession session) {
        ThemeDisplay themeDisplay = (ThemeDisplay)  session.getAttribute("THEME_DISPLAY");
    }


The problems what I see in the above technique is

  1. User can access DWR methods even after his portlet session ends, since DWR Session and portlet session are different
  2. Inverse of the above, A DWR session can expire while portlet session is still active  

JPA 2.0 enums with custom values

Let's consider we have this enum



public enum EmpType {

FULL_TIME("e1"), PART_TIME("e2");

private String val;

private EmpType(String val) {

this.val = val;

}

@Override

public String toString() {

return val;

}

}

And the entity



@Entity
@NamedQueries({
@NamedQuery(name="Employee.findByEmployeeType", query="SELECT e FROM Employee e WHERE e.employeeType = ?1")
})

@Access(AccessType.FIELD)

public class Employee implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;

@Transient
private EmpType empType;


public Long getId() {

return id;

}


public void setId(Long id) {

this.id = id;

}


public EmpType getEmpType() {

return empType;

}


public void setEmpType(EmpType empType) {

this.empType = empType;

}


@Access(AccessType.PROPERTY)
@Column(name="employee_type")
protected String getEmployeeType() {

return empType.toString();

}


protected void setEmployeeType(String employeeType) {

for ( EmpType empType : EmpType.values() ) {

if ( empType.toString().equals(employeeType)){

this.empType = empType;

}

}

}


@Override
public String toString() {

return " ID : " + id + ", employee type : " + empType;

}


}


Note : Please checkout how i'm using @Access annotations at two different places, they are mandatory.


public class Main {


public static void main(String[] args) {

Main m = new Main();

Employee e = new Employee();

e.setEmpType(EmpType.PART_TIME);

em.persist(e); // assume we are persisting this entity


m.executeQuery(EmpType.PART_TIME);


}


public void executeQuery(EmpType emptType) {

EntityManagerFactory emf = Persistence.createEntityManagerFactory("PrepApp1PU");

EntityManager em = emf.createEntityManager();


Query query = em.createNamedQuery("Employee.findByEmployeeType");

query.setParameter(1, emptType.toString());

List list = query.getResultList();

System.out.println ( list.get(0) );


}


}




the above code will save entity as follows


ID EMPLOYEE_TYPE

1 e2


Also please carefully checkout how i'm searching employees based on enums. Also carefully checkout getEmployeeType(), setEmployeeType method signatures



the executeQuery method will print this

ID : 1, employee type : e2

Monday, September 6, 2010

JPA Compound Primary Keys Explained

The whole purpose of this article is to explain JPA Compound Primary Keys in a simple way.

Some Entities needs to have a primary key based on more than one field (eg Legacy DB), so we don't have much choice here. JPA supports two ways of configuring compound primary keys however we are going to focus on the one which I feel makes Entities and Queries easy to read and understand.

Lets take an example of a PhoneDirectory Entity which stores Phone No, Ext and Employee name, many employees can have same phone no but with different ext so our candidate for primary key is Phone No and Ext. We need to follow just couple of steps write this entity

Step 1:

1. Create PhoneId class as show below
2. This class should have equals(), hashcode() and should implement Serializable
3. And should be annotated with @Embeddable



import java.io.Serializable;
import javax.persistence.Embeddable;

/**
*
* @author intesar
*/
@Embeddable
public class PhoneId implements Serializable {

private String phoneNo;
private String ext;

public PhoneId() {
}

public PhoneId(String phoneNo, String ext) {
this.phoneNo = phoneNo;
this.ext = ext;
}

public String getExt() {
return ext;
}

public void setExt(String ext) {
this.ext = ext;
}

public String getPhoneNo() {
return phoneNo;
}

public void setPhoneNo(String phoneNo) {
this.phoneNo = phoneNo;
}

@Override
public boolean equals(Object obj) {
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final PhoneId other = (PhoneId) obj;
if ((this.phoneNo == null) ? (other.phoneNo != null) : !this.phoneNo.equals(other.phoneNo)) {
return false;
}
if ((this.ext == null) ? (other.ext != null) : !this.ext.equals(other.ext)) {
return false;
}
return true;
}

@Override
public int hashCode() {
int hash = 7;
hash = 47 * hash + (this.phoneNo != null ? this.phoneNo.hashCode() : 0);
hash = 47 * hash + (this.ext != null ? this.ext.hashCode() : 0);
return hash;
}
}




Step 2 : Use PhoneId inside PhoneDirectory Entity


import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.NamedQueries;
import javax.persistence.NamedQuery;

/**
*
* @author intesar
*/
@Entity
@NamedQueries({
@NamedQuery(name="PhoneDirectory.findByPhoneNo", query="SELECT p FROM PhoneDirectory p WHERE p.phoneId.phoneNo = ?1")
})
public class PhoneDirectory implements Serializable {

private static final long serialVersionUID = 1L;
@EmbeddedId
private PhoneId phoneId;
@Column(name = "employee_name")
private String employeeName;

public String getEmployeeName() {
return employeeName;
}

public void setEmployeeName(String employeeName) {
this.employeeName = employeeName;
}

public PhoneId getPhoneId() {
return phoneId;
}

public void setPhoneId(PhoneId phoneId) {
this.phoneId = phoneId;
}

@Override
public int hashCode() {
int hash = 0;
hash += (phoneId != null ? phoneId.hashCode() : 0);
return hash;
}

@Override
public boolean equals(Object object) {
// TODO: Warning - this method won't work in the case the id fields are not set
if (!(object instanceof PhoneDirectory)) {
return false;
}
PhoneDirectory other = (PhoneDirectory) object;
if ((this.phoneId == null && other.phoneId != null) || (this.phoneId != null && !this.phoneId.equals(other.phoneId))) {
return false;
}
return true;
}

@Override
public String toString() {
return "prepclass1.PhoneDirectory[id=" + phoneId + "]";
}
}




And here are some test cases


import java.util.List;
import javax.persistence.EntityManager;
import javax.persistence.EntityManagerFactory;
import javax.persistence.Persistence;

/**
*
* @author intesar
*/
public class Main1 {

/**
* @param args the command line arguments
*/
public static void main(String[] args) {
// TODO code application logic here
Main1 m = new Main1();
PhoneDirectory pd = new PhoneDirectory();
PhoneId phoneId = new PhoneId("800-000-0000", "123");
pd.setPhoneId(phoneId);
pd.setEmployeeName("Intesar");
m.persist(pd);

System.out.println ( m.executeQuery(phoneId));

System.out.println ( m.executeQuery(phoneId.getPhoneNo()).get(0));


}

public void persist(Object object) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PrepClass1PU");
EntityManager em = emf.createEntityManager();
em.getTransaction().begin();
try {
em.persist(object);
em.getTransaction().commit();
} catch (Exception e) {
e.printStackTrace();
em.getTransaction().rollback();
} finally {
em.close();
}
}

public PhoneDirectory executeQuery(PhoneId phoneId) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PrepClass1PU");
EntityManager em = emf.createEntityManager();
try {
return em.find(PhoneDirectory.class, phoneId);
} catch (Exception e) {
e.printStackTrace();
} finally {
em.close();
}
return null;
}

public List executeQuery(String phoneNo) {
EntityManagerFactory emf = Persistence.createEntityManagerFactory("PrepClass1PU");
EntityManager em = emf.createEntityManager();
try {
return em.createNamedQuery("PhoneDirectory.findByPhoneNo").setParameter(1, phoneNo).getResultList();
} catch (Exception e) {
e.printStackTrace();
} finally {
em.close();
}
return null;
}
}


Also now can notice its so simple to write readable queries and also our entity is easy to understand.

Why Java Web Application UI lags ?

I've worked on more than 2 Dozen Java Web Applications in different companies and with various teams and every time I felt these applications lagged in UI compare to PHP applications. Don't get me wrong I'm trying to understand and find solution to problems what I'm seeing and I could easily learn from your exposure and experience or may be we all can understand whats happening.


Though most of the teams I've worked with were extremely talented and we wrote huge large scale applications and in fact we also had UI experts on these projects, then why couldn't we write great UI?

I feel there are two reason's for this firstly these teams are dominated by Java guys who mostly like working on server side code and they really don't enjoy working on UI and they spend enormousness time fixing performance, and other server side issues which hardly are issues for some project for an example in one of my project we spend weeks trying to fix application performance which is hardly used by 10 users per day.

Secondly most of the Java Web Applications use MVC frameworks such as (Struts, Spring MVC, JSF) and these framework requires java knowledge so most of the UI is written by Java Developers but most of people would argue that there is no harm in doing this. Though I feel there is a small issue with this practice that is since UI is written by Java Developers and they tend to use Tag Library which makes code unreadable for most of the UI Experts and hence there contribution is restricted.

If my above arguments hold good then this is what I can think of improving the situation

Let UI Experts own and create HTML pages, CSS (rather JSP pages and MVC) and use Javascript framework of their choice or company standard(JQuery, DOJO, YUI etc) and hook them to Server side components using JSON (DWR), REST (RESTFul Services) or POST (MVC Framework without Tag Libraries).

I feel we can take out lot of benefits by doing this.
1. UI Experts can parallel work on UI and that will give then a sense of ownership and we can see the results
2. Server Side guys can spend good amount of time on there domain of choice and be more productive.

Sunday, September 5, 2010

JPA Lifecycle Callback Events

Typical Entity Life-cycle

  • Persist   - Creating Entity for the first time.
  • Merge   - Updating detached Entity
  • Load     - Loading Entity from Database
  • Delete   - Deleting Entity from Database


JPA provides total of 6 Annotations for Life-Cycle Callback events.

  1. @PrePersist
  2. @PostPersist
  3. @PreUpdate
  4. @PostUpdate
  5. @PreRemove
  6. @PostLoad


Following two ways to utilize the above annotations.

Case 1: Defining inside Entity class

Any method can be annotated with one or all annotations, though they should follow these rules.


  1.  Method can have any name
  2.  No parameters
  3.  Return type of void
  4.  Method should not be final or static
  5.  No Checked exceptions should be thrown
  6.  Any annotation can be only used on one method


Example Code Snippet - 1

@Entity
public class Employee implements Serializable {
...

@PrePersist
@PostPersist
@PreUpdate
@PostUpdate
@PreRemove
@PostLoad
public void updateDate() {
    // this method will executed on all the lifecycle events.
}
}

Way 2 : Using Entity Listeners Classes
This is very nice way of using the annotations.

Example Code Snippet - 2


@EntityListeners({LastAccessDateListener.class})
public class Employee implements NamedEntity {
...
}

public class LastAccessDateListener {
@PrePersist
@PostPersist
@PreUpdate
@PostUpdate
@PreRemove
@PostLoad
public void updateDate(Employee e) {
  // this method is in totally separate class
}

}

LastAccessDateListener class doesn't have to be annotated or extend any other class.

Friday, September 3, 2010

JPA and Enums

There are different ways of configuring enums inside JPA entity which yields different results.

Let's consider we have this enum

public enum EmpType {
FULL_TIME, PART_TIME;
}

And the entity

@Entity
public class Employee implements Serializable {

private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column
private String name;
@Enumerated
private EmpType empType;

..
}

To use enum we have to annotate field with @Enumerated

Employee e = new Employee();
e.setId(1L);
e.setName("na");
e.setEmpType(EmpType.FULL_TIME);
em.persist(e);



the above code will save entity as follows
ID EMPTYPE NAME
1 0 na

This is because all the enum's in EmpType are indexed starting from zero, so if we change order or introduce a new enum in middle we lose the context in Employee table.

Instead use this @Enumerated(EnumType.STRING) which save the above entity as

ID EMPTYPE NAME
1 FULL_TIME na

If you are looking for more advance mapping then consider this post
Advance Enums JPA 2.0