私はここで紛失しています。おそらく、私のHibernateの専門知識は他の領域よりも弱いので、おそらく明らかです。Hibernateは既存のデータを移行するために埋め込み可能なクラスをスワップします
レガシーコードでは、ハイバーネート@Entity
クラスFoo
があります。その特性の一つはこれです:
private OldBar bar = new OldBar();
OldBar
は単一の列、foobar
を使用しています@Embeddable
クラスです:
@Embeddable
public class OldBar {
private String fooBar;
@Column(length = 10, nullable = false)
private String getFooBar() {
return fooBar;
}
@SuppressWarnings("unused")
private void setFooBar(String fooBar) {
this.fooBar = fooBar;
}
}
元の問題は、私はOldBar.fooBar
で何かをするために必要なことですが、元のデザインには制限があり、このフィールドをプライベートにしてサブクラス化するのを防ぎましたので、もう1つのクラスを置き換えてプライベートフィールドにアクセスするために、別のクラス全体を作成する必要がありました(NewBar
)。
private NewBar bar = new NewBar();
私はfoobar
列内の既存のデータを持っているので、これをやってみたかった、と私はNewBar
もEmbeddable
であり、同じ@Column
指定を持っているので、私はクラスFoo
でフィールドをスワップアウトだけのことができると考えました私はこのデータをOldBar
の代わりにNewBar
と透過的に使いたいと思っていました。
トレースログ私は、コンストラクタが呼び出されたときに期待通りに、NewBar()
のデフォルトバージョンでFoo()
が作成されていることを確認しました。しかし、タイムコードはFoo.getBar()
と呼ばれ、何らかの理由でbar
がnull
です!私は何らかの理由でHibernateがnull
に設定していると仮定していますが、foobar
列からデータを読み込み、NewBar
のインスタンスを作成するのはなぜですか? OldBar
をNewBar
の代わりに入れても、なぜそれが再び動作するのですか?確かに、データベースには、@Embeddable
クラスのどれがクラスにマッピングされているかについての情報はありません。
更新:これは見知らぬ人と見知らぬ人になります。時々私はコードを一晩中受けさせ、翌日には動作します!それとも、翌日にはうまくいかない!ちょうど今は動作しませんでした(つまり、foobar
プロパティはデータベースの値ではなくnull
に設定されていました)ので、クラスExactCopyOfOldBar
を作成してOldBar
の場所に配置してください。それはうまくいった!だから私はNewBar
に戻って---私の一時的な変更を元に戻すだけです。これまでになかった時には、それはまだ機能しました! Hibernateが値をシリアライズし、データベースから取得しないキャッシュがありますか?これは非常に奇妙です。
更新:今や私はNewBar
をまったく動作させることができなくなりました。私はOtherBar
を作成します。これは基本的にNewBar
と同じですが、別の名前が付いています。プラグインして正しく動作し、正しく埋め込まれた文字列を読み込みます。私はNewBar
に戻って、null
をもう一度得る。何が起こっている?
Foo
が十分に単純であり、
net.databinder.auth.hib.AuthDataApplication.getUser(String username)
によってロードされていること
注:私はFoo
(ユーザ)の表は、正しいデータを持つ単一の行を有することが何度も何度も検証してきた
return (DataUser) Databinder.getHibernateSession().createCriteria(getUserClass())
.add(Restrictions.eq("username", username)).uniqueResult();
と最も重要なのは、foobar
フィールドにデータがあることです。なぜHibernateは私にnull
foobar
フィールドのFoo
を返すのですか? NewBar
からOtherBar
に切り替えると、もう一度動作を開始するのはなぜですか?私はそれを一晩中放置した後、なぜ終日働いてから仕事を止めますか?
私はこれが本当だと仮定していますが、あなたはそれを言っていません: 'Foo.bar'は' @ Embedded'とマークされていますか? –
@Tim Pote:実際は、奇妙なことに、元の(動作している)レガシーコードでは、@埋め込みとしてマークされていませんでした。 'OldBar'を' NewBar'に変更したときに '@ Embedded'の有無にかかわらず試してみましたが、それは違いはありませんでした。 –
@Tim Pote:私はHibernate [documentation](http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/)から、 "もしプロパティの型@Embeddableとしてアノテートされていて、@Embeddedとしてマップされているので、技術的に '@ Embedded'部分はオプションです。 –