Wednesday, December 30, 2009

Hibernate3 Tip#3: Methods You Should Override

Just some general best practices that have saved me considerable development time as I've worked with Hibernate3:
  • Always override equals(). Objects that are equal as plain Java objects are often not equal in Hibernate3 because of the identity problem. Hibernate considers the object's persistent state, database identity, and other factors to determine if two objects are equal. By overriding equals(), you set a standard of equality both Hibernate and Java can use.
  • It is a bad idea to override equals() in subclasses. Hibernate does not behave well.
  • Always override hashCode() and provide your own implementation based on the class's attributes that are expected to change rarely. I use the class identifier commonly. Actually, overriding equals() almost always requires overriding hashCode().
  • When you implement equals() and hashCode(), always use property accessors - getXX()/setXX(), POJO style. Hibernate allows the use of proxy classes or references that may no contain actual data if you call their properties directly. Believe me, this is a pain to debug!
  • Always make classes Comparable in case objects of the class end up in collections that require this feature (such as SortedSet or other collections that use a class-dependent Comparator). This gives you the flexibility to switch collection types whenever (e.g. from List to Set) without further base code changes.
  • I also always override toString() because I hate seeing memory addresses as representations of objects. I use it for debug information that I can print out and understand, and that uniquely identifies the object for me.
Pretty much every OOP project I've worked on, these are some of the first tasks that get done. If developers would just get in the habit of these best practices, I wouldn't dread inheriting their projects so much.

Tuesday, December 29, 2009

Hibernate3 Tip#2: Enable Automatic Dirty Checking

In database parlance, when you read a record from a table and update some of its fields in memory, the record is considered dirty. Dirty checking avoids unnecessary database write actions by performing SQL updates only on the modified fields of persistent objects. Hibernate3 JPA can do automatic dirty-checking for you via an annotation to the entity:
@org.hibernate.annotations.Entity(
dynamicInsert=true, dynamicUpdate=true
)
The dynamicInsert property is really only necessary to prevent writing NULL values to database fields. But if the changes involve setting NULL values (bad practice), you should probably turn it off.
I can think of three possible implementations for dirty checking:
  1. Caching a clean copy of the record and maintaining an edit copy of the persistent object. When an SQL update is due, the copies are compared and changes extracted from the edit copy for update. Obviously memory-intensive as 2 copies of a record are maintained at all times.
  2. Keeping track of which fields changed.
  3. Doing a SQL query just before updating and doing the necessary reductions to determine what changed.
I do not know which strategy Hibernate3 uses. Either way, the performance hit is minimal compared to rewriting whole table rows in the database - depending on how many fields each record has. It is recommended when you have more than 50 fields where any given update affects less than 25% of the fields (if you want hard numbers).

Monday, December 28, 2009

Hibernate3 Tip#1: Persistent Lifecycles

For application developers that use the Hibernate3 JPA, it is crucial that you learn the different persistent states an object can be and what methods/functions cause them to transition to what other states. The states are: transient, persistent, detached, and removed. You must also know how a persistent context works, the ACID (atomicity, consistency, isolation, durability) principles for database transactions, and basics of object identity (Java's equality is NOT the same as database record equality).

You can find out more about Hibernate3 at https://www.hibernate.org/.

Tuesday, August 25, 2009

TimeTrak: The Webserver

Whenever you do web development, you will inevitably have to use a web server. I use the term 'web server' to generally mean HTTP servers, webservers, and application servers. If your website only dishes out HTML and other static content without server-side processing, you probably just need an HTTP server. If you expect dynamic content and server-side processing, perhaps a webserver is what you need. If you'll be running (web-oriented) programs and services, heavyweight back-end processing, or on vendor-specific stacks, etc, you should research application servers. Application servers can do everything webservers do, and webservers can do everything HTTP servers do.

The choice of a web server depends on the programming language that will be used to implement the business layer (applications, data processing, business rules, generation of content, etc). Don't forget that some web servers might be supported on specific operating system platforms as well e.g. IIS is a Microsoft-only deal. Others can be vendor-specific, requiring you to use their database programs or hardware. Web servers can cost anywhere from free/open-source (e.g. Apache Tomcat) to very expensive enterprise class subscriptions (e.g. Microsoft Web server). The cost is usually for value-added services and features beyond basic web-serving such as multi-processor support, load balancing, clustering, security, availability/redundancy, technical support, or other vendor-specific bells-and-whistles.
The web server is where your application architecture is implemented. The web application will depend heavily on the services provided by the web server, including database access and security.

TimeTrak shall be implemented in Java, and will only need a webserver such as Apache Tomcat. With this setup, I can use the JSP/Servlet container to generate dynamic content, and a JDBC-compliant driver to access the database. I can use the full power of the Java programming language to implement the web application. The business layer shall be implemented with Spring MVC, and data layer with Hibernate. Your choice of web server must support your architecture decisions squarely. This is why some businesses prefer stacks such as those from JBOSS, IBM, or Oracle. Other decisions you must consider before choosing a web server include: how you will be building and deploying the application, testing strategy, and security. Make sure your customer is on-board with the decision, as it is potentially the most expensive if you had to change things completely.

A note about security: after installing a web server, take time to lock it down, as it is the gateway to the outside world. A lot of website security breaches take advantage of web server default settings and other vulnerabilities for which patches and best practices would have saved the day. Make sure you are aware which ports the web server opens, or operating system services it depends on, and secure them accordingly.

Other reading:
http://www.sun.com/bigadmin/content/developer/howtos/webserver_part1.html
http://tools.devshed.com/c/a/How-To/How-To-Choose-The-Web-Server-For-You/
http://webdesign.about.com/cs/webservers/bb/abwebservers.htm