2011-01-12 9 views
6

私はJava、Spring、Hibernateを使用するプロジェクトを最近OracleからMySQLに変更しました。コード内のいくつかのプロパティが、 "release"のようにMySQLの予約語である場合がいくつかあります。Hibernate:MySQLではバッククイックを使用しますが、HSQLでは使用しません。

コードとそれ以降のgetter/setterメソッドのプロパティの名前の変更、それらのメソッドを呼び出すコードの更新2)@Column(name = "` release` " )。これは、データベースと対話するときに名前を引用するように休止状態を指示します。

私は、より多くのものを壊す可能性を減らすために最初のアプローチから離れることを好むでしょう。 2番目のアプローチは「OK」ですが、MySQL固有のものになります。私たちの開発者では。私たちはHSQLを使用します。このHSQLは、これらの列名の回りのバッククォートが嫌いです。

org.hibernate.mapping.Columnクラスを見て、Columnをサブクラス化してHibernateに自分自身のColumnクラスを使用させることができるならば、私は潜在的にオーバーライドできる "getQuotedName"メソッドを持っているのが分かります。

a)コードベースをリファクタリングする必要がない(プロパティ名を変更するb/c、getter/setterメソッドなど)、b)アプリを依然として使用したいという好ましいアプローチに基づいて、この問題を解決する最善の方法HSQLとMySQLで動作します。

いくつかの列命名修正をオン/オフに切り替えることができるプロパティファイル内のプロパティを持つことは合理的です。私は、私はカスタムネーミング戦略を使用して、 "columnName"メソッドをオーバーライドして、バッククォート内のカラム名を囲んでみることを試みました。これはMySQL上でさえもうまくいきません。

+1

明らかに、hibernate.globally_quoted_identifiers(http://opensource.atlassian.com/projects/hibernate/browse/HHH-4453)が使用できる(hibernate 3.5の私が信じるように)新しいプロパティがありますが、文書化されていませんhttp://opensource.atlassian.com/projects/hibernate/browse/HHH-5673)。 私はHibernate 3.3を使用しているので、これは私にとっては選択肢ではありません – codecraig

+0

あなたの質問にちょうど答えましたが、私はこのことについて知らなかったのです。 – jpkrohling

答えて

1

バックチックソリューションは良いと思います。しかし、それが機能しない場合、または特定のJPA製品の文書化されていない機能を使用したくない場合は、なぜ(または最も一般的な)データベースに予約されていない列名を使用しないでください。

Javaプロパティの名前を変更する必要はありません。列名を指定する必要があります。

+0

良い点...それは十分簡単です。私はプロパティ名がdbの列名と一致するのが好きですが、それは必須ではなく、DBの列名をJavaプロパティ名に非常に近い名前に変更できます。 – codecraig

0

バックヒントを使用します。 Hibernateに、その識別子を適切に引用するように指示するのがあなたの方法です。バッククォートはMySQLのクォート文字としても使用されるのは偶然のことです。このバッククォートは、データベースのクォート文字に変換されます。引用符をデフォルトの振る舞いとして追加することに関して、私はHibernateがそのようなオプションを持っているかどうか分からない。ドキュメンテーションの中には可能なオプションが記載されていないので、テストスイートでもこのようなことは覚えていません。しかし、私はそれが良い考えだとは思わない、 "予約されたキーワード"は例外であり、ルールではない。

+0

@Column(name = "' .... '")をコード内の予約語であるプロパティに追加する必要がありますか? 私は命名戦略を使用し、 "columnName"メソッドをオーバーライドして、カラム名にバッククォートを追加しようとしましたが、例外的にMySQLで例外が発生しました: org.hibernate.MappingException:論理カラム名:foobar.'thing_id' => 'thing_id'と 'thing_id' – codecraig

+0

はい、@Column(name =" '' something'' ")は通常の方法です。私は、命名戦略の変更もうまくいく可能性があり、あなたが見ているこのエラーはバグだと思うでしょうが、確認するためにはそれをさらにデバッグする必要があります。いずれにしても、すべての識別子をグローバルに引用するプロパティが見つかったようです。それも解決策になります。 – jpkrohling

+0

はい、Hibnerate 3.5以降を使用していた場合、識別子をグローバルに引用するプロパティが機能する可能性がありますが、現在は3.3で固まっています。 @Columnを試してみます。私はPythonスクリプトを書いて、SQL DDLの列名をすべてチェックして予約語を使用しているかどうかを確認しましたが、今は問題が1つしかないので、この1つのケースでコードをリファクタリングすると、新しいバージョンを使用する場合、Hibernateはより良いアプローチ(例えばグローバルプロパティを使用する)を持っているように見えるので、悪いことではありません。 – codecraig

関連する問題