The Source for Java Technology Collaboration
User: Password:



Jacob Hookom's Blog

December 2005 Archives


Handling Type Codes in Your Domain Models

Posted by jhook on December 14, 2005 at 09:43 AM | Permalink | Comments (3)

With complex enterprise systems, we often times find ourselves with lots of 'flags' or 'types' within our database tables. Utilizing Hibernate's UserType facility, we can handle these types in such a way that will carry extra behavior and information within your domain models.

You probably all have them, those VARCHAR(2) or VARCHAR(1) fields in your tables that describe the type or source of the data. One approach would be to explicitly map that character data as a String or char property to your domain models. I've also seen a lot of discussion around using enums within JSE 5 to handle these values. But often, you need to translate that code into additional behavior or just human-readable format.

The approach we've taken is to create simple Objects that have an identity to match the 'type' in the database and then include extra information. An example of handling purchase orders, where each line item has a status:

public class LineStatus {

    // matches db 'type field
    private final String id;

    // used in business logic
    private final boolean accepted;

    // human readable for invoice
    private final String summary;

    // human readable for web app
    private final String detail;

    public LineStatus(String id, boolean accepted, ...) {
       this.id = id;
       this.accepted = accepted;
       ...
    }

    // getters only

    // implement hashCode, equals, and toString

    public final static LineStatus BACKORDERED = ...;
    public final static LineStatus ACCEPTED = ....;
    public final static LineStatus REJECTED = ....;
    public final static LineStatus RESTRICTED = ....;

    
    private final static Map statuses;

    static {
       // initialize our set of possible statuses
    }

    public static LineStatus get(String id) {
        LineStatus s;
        if (id != null) {
            s = statuses.get(id);
        }
        // default if s is null?
        return s;
    }
}

Now we have a basic Domain Type that we can program off of in relation to our OrderLines. This Domain Type will also include additional (static) data that can be carried into your application, based on that one two character field from the database. The addition of 'summary' and 'detail' properties also provides our applications with consistent, human-readable, information as it relates to that status.

The next step is configuring this Type for Hibernate by creating a LineStatusType.


public class LineStatusType implements UserType {

    private static final int[] SqlTypes = new int[] { Types.VARCHAR };

    public LineStatusType() {
        super();
    }

    public int[] sqlTypes() {
        return SqlTypes;
    }

    public Class returnedClass() {
        return LineStatus.class;
    }

    public boolean equals(Object x, Object y) throws HibernateException {
        return (x == y) || (x != null && y != null && (x.equals(y)));
    }

    public int hashCode(Object value) throws HibernateException {
        return value.hashCode();
    }

    public Object nullSafeGet(ResultSet rs, String[] names, Object owner)
            throws HibernateException, SQLException {
        String id = rs.getString(names[0]);
       	return LineStatus.get(id);
    }

    public void nullSafeSet(PreparedStatement st, Object value, int index)
            throws HibernateException, SQLException {
        if (value != null) {
            st.setString(index, ((LineStatus) value).getId());
        } else {
            st.setNull(index, Types.VARCHAR);
        }
    }

    public Object deepCopy(Object value) throws HibernateException {
        return value;
    }

    public boolean isMutable() {
        return false;
    }

    public Serializable disassemble(Object value) throws HibernateException {
        return (Serializable) value;
    }

    public Object assemble(Serializable state, Object owner)
            throws HibernateException {
        return state;
    }

    public Object replace(Object original, Object target, Object owner)
            throws HibernateException {
        return original;
    }
}

That's it. Some more complex objects could have a few of these Domain Types allotted. Are there other approaches to handling type flags in your databases?



Move Over Apache

Posted by jhook on December 08, 2005 at 09:47 PM | Permalink | Comments (1)

A little over a year ago, the JavaServer Faces specification caught my interest. I've always considered myself a 'do it yourself' programmer and went as far as to start my own implementation of the JavaServer Faces specification.

I reached a point where I thought I really had something and was left with a few options: contribute to Apache, publish it on my own, or contribute to Sun's reference implementation. After much thought, here's an opportunity to contribute to 'the' standard and I joined the reference implementation at Java.net. By far, it was the best decision I'd ever made in my programming career.

One year later. In that time, I've been able to be a committer on the reference implementation of JSF, immediately joined the JSF EG, then invited to the Web Tier EG, given my own sub-project (Facelets) under Sun, added as one of the first Java Champions, and even had a few job offers since. I'd like to throw in the fact that because of that one decision, I've had the opportunity to meet and talk with industry names that I've only read on bindings of books or in articles-- Jason Hunter, Gavin King, Craig McClanahan, Ed Burns, David Geary, Kito Mann, etc.

The reason why I'm writing this blog is that so many out there have shied away from contributing to Sun's open source initiative under the CDDL. I'd like to use my last year as an example of the opportunities that are provided by making that one decision, the same decision that any of you can pursue.

Apache isn't the only body out there accepting eager developers and I guarantee that you will get a lot more recognition with an industry name like Sun.

I know that joining an open source project is driven by your own personal interests, maybe it's the new EJB3, Web Services, or JSF to name a few?





Powered by
Movable Type 3.01D
 Feed java.net RSS Feeds