Wednesday, December 10, 2008

Adding logic to accessor methods in Hibernate

While reading Java Persistence with Hibernate I came across an interesting fact that Hibernate does not require you to have getter and setter methods. On top of that it does not rely on them to check if the value of a property has changes. This means that you can amend and change your data before giving it away from getter.

Assume you have a Person class and a person has a first and second names, both must be capitalized.

First, you can add logic into your methods, like validation:

public class Person{
   
private String firstName;
   
private String secondName;
   
public String getFirstName(){
       
return firstName;
   
}
   
public void setFirstName(String firstName)
               
throws InvalidNameException{
       
if(!StringUtil.isCapitalized(firstname))
           
throw new InvalidNameException(firstname);
       
this.firstname = firstname;
   
}
}

Second, you can have convenience methods:

public class Person{
   
private String firstName;
   
private String secondName;
   
public String getName(){
       
return firstName + ' ' + secondName;
   
}
   
public void setName(String name){
       
StringTokenizer t = new StringTokenizer(name);
       
firstname = t.nextToken();
       
secondname = t.nextToken();
   
}
}

NOTE:
The only exception is collections! You can not change collection values in your getter and setter methods. Otherwise, Hibernate will issue an UPDATE SQL statement every time it synchronizes with database.

To conclude, you can change a property's value also add logic in your getter/setter methods if and only if the property is not a collection.

Tuesday, December 9, 2008

Convenience methods in Parent / Child relationships in Hibernate

One of the most used associations in ORM is a parent/children relationship. Each parent has a set of children and a child has only one parent. So this is a snippet of a convenience method to manage children from a great book I'm currently reading Java Persistence with Hibernate.

public void addChildCategory(Category childCategory){
   
if(childCategory == null)
       
throw new IllegalArgumentException("Null child category!");
   
if(childCategory.getParentCategory() != null)
       
childCategory.getParentCategory().getChildCategories().remove(childCategory);
   
childCategory.setParentCategory(this);
   
childCategories.add(childCategory);
}

Similarly you can create a removeChildCategory() convenience method.

You probably want to make this methods public and getter/setter methods of the children field private. This will enforce cardinality of the association.

TIP:
Hibernate does not require your entity class to have getter and setter methods. Hibernate will access your entity class properties using Java's Reflection API. So even though your properties are private Hibernate will be able to access them.

In case you have a bidirectional association and your entity class has getter methods than the getter returns a modifiable reference to your children set. This may lead to potential cardinality problem. So, I suggest to wrap your collections in getter method with Collections.unmodifiableCollection(children) and Collections.unmodifiableSet(children).

How to run a stand alone HSQLDB database as a service

HSQLDB database is an open source database fully written in Java. It's light weight and supports wide range of SQL standard. As I already mentioned it's fully written in Java and it can run standalone or within your Java application.

So you can embed it in your own application as a library. All you need is to include hsqldb.jar (593KB) file in your libs folder.

Also it's a great database to use while working on your project. You can add it as a target in your Ant build or in Maven.

Anyway, it's a great tool to have in your "Web Developers Toolkit". Back to the point. I needed it to run continuously in the background since my IDE reads data from it to make my life easier. So this is what you need to run in your console to run HSQLDB in the background:

java -classpath /path/to/hsqldb.jar org.hsqldb.Server

To stop the service press CTRL+C.

Friday, December 5, 2008

How to insert colorized code to any blog including Blogger, code to html converter

I recently started blogging about my experience with bloated, messy and mainly standards based programming language - Java. So I needed a way to paste my Java, XML and other programming language codes in more readable and colored way. So after a little research I found an online HTML generator. You can paste your code and it will generate colored version of your code in HTML. Than you can switch to HTML version in your editor paste the code and wua la:

package messy.java;
public class SomeClass {
private static final Integer myVar;
static {
try {
// Some comment
myVar = new Integer();
} catch (Throwable ex) {
System.err.println("Error:" + ex);
throw new ExceptionInInitializerError(ex);
}
}
}

If you are using Windows Live Writer to post your entries, than you are lucky, there is a plugin for you and for those who does not there is a stand alone version as well.

Happy blogging :)

Minimum set of required libraries for Hibernate

Hibernate is a great ORM framework. It makes your life much easier and increases your effectiveness. I'm still learning it and using it for almost all of my projects (of course, I don't blindly use it, I try to find arguments to support this decision). Another great tool to improve your programming effectiveness and make your programmer life much easier is an Apache Maven. I'm sure you already using Apache Ant, trust me if you like Ant, you will love Maven!

If you're using Maven then you are lucky and don't really need to know what are the prerequisites for Hibernate. Maven finds and loads them for you!!! But anyway if you are not using Maven nor Maven plugin for Ant then here is the list of required libraries for Hibernate project:

+libs
- antlr.jar
- cglib.jar
- asm.jar
- asm-attrs.jars
- commons-collections.jar
- commons-logging.jar
- hibernate3.jar
- jta.jar
- dom4j.jar
- log4j.jar

The last log4j.jar is not required, but nice to have :)

Thursday, December 4, 2008

Access to restricted URI denied" code: "1012

I was working on the interface for our catalogue/directory structure. We use great JavaScript library jQuery and I came up to this problem:

Access to restricted URI denied" code: "1012
xhr.open(type, s.url, s.async);

(This error is produced in Firebug, plug-in for Firefox.)

The error occurs when it tries to do an AJAX request call to local resource. So to solve this problem you need to deploy your files to your web server or run one locally.

Hibernate: Self-mapping Parent/Child relationship using annotations

Yesterday I wrote about self mapping collections in Hibernate. I used XML mapping document to define the relationship. Today I would like to show how to achieve the same result using Java Annotations. So without further adu here is the java class:

@Entity
@Table(name = "CATALOGUE")
public class Catalogue implements Serializable {

    @Id
    @Column(name = "ID")
    private Integer id;

    @Column(name = "CONTENT", nullable = true)
    private String content;

    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private Catalogue parent;

    @OneToMany(mappedBy = "parent")
    private Set<Catalogue> children = new HashSet<Catalogue>();

    public Catalogue() {
    }

    public Integer getId() {
        return id;
    }

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

    public String getContent() {
        return content;
    }

    public void setContent(String content) {
        this.content = content;
    }

    public Set<Catalogue> getChildren() {
        return children;
    }

    public void setChildren(Set<Catalogue> children) {
        this.children = children;
    }

    public void addChild(Catalogue child) {
        child.setParent(this);
        children.add(child);
    }

    public Catalogue getParent() {
        return parent;
    }

    public void setParent(Catalogue parent) {
        this.parent = parent;
    }
}