But then come your local friendly DBAs, who will be glad to tell you about their set of database naming conventions -- conventions that date from before the demise of the dinosaurs, and that aren't about to change! These database conventions usually have quite valid reasons to exist, and in any case DBAs tend to be a conservative lot. What's a developer to do?
One simple solution is to use the name
attribute of the @Entity
and @Column
annotations to override the default name generation, as shown in Listing 4.
Listing 4. Annotating the Client class to customize the generated SQL schema
@Entity(name="T_CLIENT")
public class Client implements Serializable {
...
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name="CLIENT_ID")
private Long id;
@Column(name="FIRST_NAME")
private String firstName;
@Column(name="LAST_NAME")
private String lastName;
...
}
This will work, but it becomes a wee bit tiresome when you have a lot of tables. Indeed, you have to remember to do it for each and every table and field. There has to be a better way, right? Well, there is! You can define a naming strategy in your Hibernate session factory to override the default behavior. This basically involves writing a class that tells Hibernate how you want table and field names formatted.
A good place to start is the ImprovedNamingStrategy
class, which basically converts camel case class names (SomeDomainEntity
) to names in lower case with underscores (some_domain_entity
). You need to provide this class when you create your Hibernate session at startup. If you are using Spring, you simply create a naming strategy bean and provide it to the session factory. Listing 5 illustrates what a typical Spring configuration would look like.
Listing 5. Configuring automatic schema generation in Spring
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="configLocation" value="classpath:/hibernate.cfg.xml" />
<property name="configurationClass" value="org.hibernate.cfg.AnnotationConfiguration" />
<property name="namingStrategy" ref="namingStrategy" />
</bean>
<bean id="namingStrategy" class="org.hibernate.cfg.ImprovedNamingStrategy"/>
With this naming strategy, Hibernate would generate a script that looks something like the one in Listing 6.
Listing 6. The SQL script created using the Spring Hibernate configuration
create table client (
id bigint generated by default as identity (start with 1),
first_name varchar(255),
last_name varchar(255),
...
primary key (id)
);
That's nice, but it doesn't always solve all your problems. Typically, database naming conventions are more demanding. For example, each table might have to start with T_ and be in uppercase (T_CLIENT for the Client
class, for example). Or each field in a table might need to start with a table-specific prefix (CLI_FIRST_NAME and CLI_LAST_NAME, for instance). To automate this sort of constraint, you need to write your own naming strategy implementation.