Hibernateで自動生成されるカラム名に文字を付加する

最近PostgreSQLからMySQLに乗り換えたのですが、Hibernateがhbm2ddlでテーブルを生成する時にエラーが出るようになってしまいました。Hibernateでテーブルの自動生成をすると、フィールド名がそのままカラム名になるため、MySQL予約語と同じフィールド名があるとエラーになってしまうようです。PostgreSQLだとなぜエラーにならないのか良く分かりませんが、ひとまず対処方法を調べてみました。

手動でDDLを書く場合は''で囲めば良いだけなんですが、hbm2ddl(というかMySQLのDialect?)では残念ながら自動で''を付加することはしてくれないみたいです。HibernateのJiraにも何度も予約語が使えないという話が出てきますが、''で囲むと大文字と小文字を区別しちゃうといった副作用があるから実装したくないという方針のようです。

地道な解決法としては、各フィールドごとに手動で別のカラム名を設定してやることも出来ますが、もう少し機械的な方法が良いので別の手段を探してみたところ、HibernateではNamingStrategyというクラスでフィールド名をカラム名に変換しているので、それを何とかしてやれば良いことが分かりました。

今回はカラム名だけを何とかしたいので、NamingStrategyのデフォルト実装であるDefaultNamingStrategyを継承して、カラム名だけ予約語と重ならないようにするNamingStrategyを作成してみました。コード的にはこんな感じです。

@SuppressWarnings("serial")
public class SuffixNamingStrategy extends DefaultNamingStrategy {

	private String suffix = "_";

	public String getSuffix() {
		return suffix;
	}

	public void setSuffix(String suffix) {
		this.suffix = suffix;
	}

	/**
	 * デフォルトの変換を行ってカラム名を生成し、末尾に _ を足す
	 */
	@Override
	public String propertyToColumnName(String propertyName) {
		String columnName = super.propertyToColumnName(propertyName);
		return columnName + suffix;
	}
}

propertyToColumnName()といういかにもなメソッドをオーバーライドして、予約語と重ならないようにカラム名の末尾に_を足すようにしています。

NamingStrategyを作成した後は、作成したものを有効にするために、デフォルトのものと入れ替えてやる必要があります。入れ替え自体はpersistence.xmlなどにこんな感じの設定を追加するだけで良いようです。

  <property name="hibernate.ejb.naming_strategy" value="SuffixNamingStrategy" />

ここまでの設定を試してみたところ、無事にフィールド名に_が付加されたカラムが作成されました。NamingStrategyの動作をあまり理解していないので、これで正しいのかいまひとつ自信がありませんが、ひとまずは問題なく動いているようです。