Skip to content

Coding by Conventions in Hibernate by implementing NamingStrategy, ImprovedNamingStrategy

Ever thought how you could have sensible defaults with your pojos and table column mappings, just like good buddy – Ruby on Rails? Hibernate provides an extremely simple and useful API for writing custom rules and strategies for converting column names/table names to/from your pojos/domain objects to data model.

Have a look at org.hibernate.cfg.NamingStrategy

Say, you have a table CUSTOMERS with fields first_name, last_name and a foreign key address_id from ADDRESS table. Your corresponding domain object/pojo would probably have a class ‘Customer’ with the camelCase firstName, lastName.

With Hibernate 3 annotations, this is how you would annotate

@Entity
@GenericGenerator(name="id-generator", strategy = "native",
    parameters = {
        @Parameter(name="sequence", value="CUSTOMERS_ID_SEQ")
    }
)
public class Customer {

	private String firstName;
	private String lastName;
	private Address address;

	public String getFirstName() {
		return firstName;
	}

	public void setFirstName(String firstName) {
		this.firstName = firstName;
	}

	public String getLastName() {
		return lastName;
	}

	public void setLastName(String lastName) {
		this.lastName = lastName;
	}

	@OneToOne
	@Cascade(value = { CascadeType.ALL})
        public Address getAddress() {
             return address;
        }

	public void setAddress(Address address) {
             this.address = address;
       }
}

Wait! Where are the column mappings (@Column(name = “FIRST_NAME”), table names (@Table(name = “CUSTOMERS”) )and join columns (@JoinColumn(name = “ADDRESS_ID”) )?

Well, thats what Hibernate would ‘guess’ for your with a combination of it’s “sensible’ defaulting behavior and if you implement NamingStrategy or use the handy ImprovedNamingStrategy. Imagine a project with a rich domain model of over 60 pojos with several complex attributes. With just simple coding by convention, one can eliminate the redundant mappings over simple attribute names saving a lot of clutter. (and possibly trivial errors). This is one naming strategy, which handles a simple CamelCase to camel_case conversion.

All properties of an entity are automatically considered persistent, with default strategies and table/column names. You add them here for clarity and to get the same results as with the XML mapping file. Compare the two mapping metadata strategies now, and you’ll see that annotations are much more convenient and reduce the lines of metadata significantly. Annotations are also type-safe, they support autocompletion in your IDE as you type (like any other Java interfaces), and they make refactoring of classes and properties easier.

In our project, we extended the ImprovedNamingStrategy further to handle pluralization of tablenames, column names (just like RoR) & guessing foreign keys of tables (xx_id)

public class WonderfulNamingStrategy extends ImprovedNamingStrategy {
    @Override
    public String foreignKeyColumnName(String propertyName, String propertyEntityName, String propertyTableName, String   referencedColumnName) {
        return columnName(propertyName) + "_id";
    }

    @Override
    public String classToTableName(String className) {
        return pluralize(super.classToTableName(className));
    }

    private String pluralize(String name) {
        StringBuilder p = new StringBuilder(name);
        if (name.endsWith("y")) {
            p.deleteCharAt(p.length() - 1);
            p.append("ies");
        } else {
            p.append('s');
        }
        return p.toString();
    }
}

To get this working with Spring you would need to add the following to your applicationContext file: -

<bean id="sessionFactory"
		class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
		<property name="dataSource">
			<ref bean="dataSource" />
		</property>
		<property name="namingStrategy">
			<bean class="org.hibernate.cfg.ImprovedNamingStrategy" />
		</property>
  ...
  .....
  ...
>

You just made a small simulated one of the best features of RoR in Hibernate & Spring! There are many more features in Hibernate 3.2.x which have ‘sensible’ defaults. Look here for more info in the hibernate annotations ref

[Slashdot] [Digg] [Reddit] [del.icio.us] [Facebook] [Technorati] [Google] [StumbleUpon]

One Trackback/Pingback

  1.   Hibernate NamingStrategy für Oracle by Schauderhaftes on Wednesday, March 12, 2008 at 3:07 pm

    [...] der Suche nach dieser Lösung bin ich auch bei ein paar Seiten vorbeigekommen, bei denen Namenskonvention mit Hilfe einer Namingstrategy umgesetzt werden. we extended the ImprovedNamingStrategy further to [...]

Post a Comment

Your email is never published nor shared. Required fields are marked *
*
*