1

Hibernate を永続性 ORM として使用する Spring Web アプリケーションがあります。ある時点で、ユーザーは何らかのアクションを実行するためにいくつかの質問 (関連性の高いセクションに並べられています) を求められます。

私のリポジトリでは、以下の HQL によってユーザーの質問を読み込みます。

StringBuilder hql = new StringBuilder();
hql.append("select question ")
   .append("from User as user ")
   .append("left join user.definition as definition ")
   .append("left join definition.sections as section ")
   .append("left join section.questions as question ")
   .append("where user.id = :user");

Query query = getQuery(hql.toString());
query.setParameter("user.id", userId);

return query.list();


これにより、次の非常に奇妙な結果が得られます。

questions = {java.util.ArrayList@4629} size = 18
[0] = {model.Question@6692}"model.Question@49134043"
[1] = {model.Question@6693}"model.Question@ee01430"
[2] = {model.Question@6694}"model.Question@194d62f1"
[3] = {model.Question@6695}"model.Question@279ac931"
[4] = {model.Question@6696}"model.Question@230ec447"
[5] = {model.Question@6697}"model.Question@1e78234c"
[6] = {model.Question@6698}"model.Question@61556234"
[7] = {model.Question@6699}"model.Question@2ca275d8"
[8] = {model.Question@6700}"model.Question@5de6cecc"
[9] = {model.Question_$$_javassist_12@6701}"model.Question@5c12e33d"
[10] = {model.Question@6702}"model.Question@5c04e904"
[11] = {model.Question@6703}"model.Question@25c2cbee"
[12] = {model.Question@6704}"model.Question@17da89a0"
[13] = {model.Question@6705}"model.Question@c81739c"
[15] = {model.Question@6706}"model.Question@6cd0d2e"
[16] = {model.Question@6707}"model.Question@1c4a7f"
[17] = {model.Question@6708}"model.Question@415ed7e7"


注意すべき2つの奇妙な点がありますArrayList
2) もう 1 つの奇妙な点はQuestion、9 番目の位置にあるインスタンスがロードされていないことです! Hibernate が遅延読み込みに使用するプロキシです。ただし、他のすべてのインスタンスは完全に読み込まれます (HQL で定義されているように)。

これまでにこの 2 つの奇妙なことを経験したことはありません。潜在的なデータエラーについてデータベースをチェックしましたが、すべて問題ないようです...

すべてのヘルプは非常に高く評価されています!

「初期化されていない」オブジェクトの詳細ビューの下:

[9] = {model.Question_$$_javassist_12@6701}"Question@218f5a04"
handler = {org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer@6739}
    interfaces = {java.lang.Class[1]@6745}
    constructed = true
    persistentClass = {java.lang.Class@2709}"class model.Question"
    getIdentifierMethod = null
    setIdentifierMethod = null
    overridesEquals = true
    componentIdType = null
    replacement = null
    entityName = {java.lang.String@6746}"model.Question"
    id = {java.lang.Long@6747}"31"
target = {model.Question@6748}"model.Question@218f5a04"
initialized = true
readOnly = false
unwrap = false
session =  {org.hibernate.internal.SessionImpl@6749}
"SessionImpl(PersistenceContext[entityKeys=
[EntityKey[model.Question#31],        EntityKey[model.Question#20], 
EntityKey[Question#17], EntityKey[model...
readOnlyBeforeAttachedToSession = null
sessionFactoryUuid = null
specjLazyLoad = false
group = null
questionType = null
text = null
uuid = {java.util.UUID@6741}"54e505a3-68ef-44a3-bf5e-e801e3443d79"
id = null
version = null
4

1 に答える 1

2

最初のポイント (14 番目の要素が欠落しています) に答えようとします。クエリで左外部結合を使用しているため、一致する がなくても、definitionandごとに少なくとも 1 行が返されます。この場合、データベースは結果のすべてのフィールドを返します (からフィールドのみを選択しているため)。私の推測では、Hibernate はそれを.sectionquestionnullquestionArrayList

したがって、 がないものがある場合、またはdefinitionがないものがある場合は、データベースをチェックインしてください。これで最初の点が説明できます。sectionsectionquestion

左外部結合を内部結合に置き換えることもできます。これにより、null エントリが取り除かれます。クエリで外部結合を使用することにした理由はありますか?

2 番目の点については、このレコードのデータ レベルで、Hibernate が完全なオブジェクトではなくプロキシのみをインスタンス化する原因となる何かが異なると思われます。エンティティ定義を見ずに何を伝えるかは非常に困難です。識別子以外のすべてのフィールドが null であるため、Hibernate は完全なオブジェクトをインスタンス化する必要を認識していないのでしょうか?

于 2013-09-24T20:43:46.673 に答える