【问题标题】:Join vs join fetch加入与加入获取
【发布时间】:2013-09-27 13:09:31
【问题描述】:

我知道有很多关于 join 与 join fetch 的问题。 区别解释如下:

“获取”连接允许使用单个选择来初始化值的关联或集合以及它们的父对象。这在集合的情况下特别有用。它有效地覆盖了关联和集合的映射文件的外连接和惰性声明。

但是,当我有一个 Criteria 或 HQL 使用内部或外部联接而不进行获取时,我注意到实体似乎已完全获取(我的休眠映射使用 FetchType.LAZY)。 我只在写“join fetch”时才预料到这一点。 所以我看不出这种情况有什么不同。

我一定在这里遗漏了什么。 有人可以帮我澄清一下吗?

更新

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@6756} size = 18
[0]={model.Question@6800}"model.Question@10f98160[]"
    section = {Section$$_javassist_21@6873}"model.Section@7711057b[]"
        handler = {org.hibernate.proxy.pojo.javassist.JavassistLazyInitializer@6890}
            interfaces = {java.lang.Class[1]@6897}
            constructed = true
            persistentClass = {java.lang.Class@2708}"class model.Section"
            getIdentifierMethod = null
            setIdentifierMethod = null
            overridesEquals = true
            componentIdType = null
            replacement = null
            entityName = {java.lang.String@6898}"model.Section"
            id = {java.lang.Long@6881}"1"
            target = {model.Section@6899}"model.Section@7711057b[]"
                name = {java.lang.String@6909}"General"
                sequence = 1
                textStart = {java.lang.String@6910}"Some value"
                textEnd = null
                sectionVersion = 1
                status = {model.SectionStatus@6911}"ACTIVE"
                definitions = {org.hibernate.collection.internal.PersistentSet@6912} size = 1
                questions = {org.hibernate.collection.internal.PersistentSet@6913} size = 13
                validFrom = {java.sql.Timestamp@6914}"2012-01-01 00:00:00.0"
                validTo = {java.sql.Timestamp@6915}"2099-01-01 00:00:00.0"
                active = false
                uuid = {java.util.UUID@6916}"97277496-12ee-453d-9478-9fc4e1519c02"
                id = {java.lang.Long@6881}"1"
                version = {java.lang.Integer@6882}"1"
                initialized = true
                readOnly = false
                unwrap = false
                session =     {org.hibernate.internal.SessionImpl@6900}"SessionImpl(PersistenceContext[entityKeys= [EntityKey[model.PossibleAnswer#57], EntityKey[model.PossibleAnswer#56], EntityKey[PossibleAnswer#59], E...readOnlyBeforeAttachedToSession = null sessionFactoryUuid = null specjLazyLoad = false

Question 类引用了它的 Section,在堆栈跟踪中您可以看到 Section 已完全加载,尽管我没有在 HQL 中指定“join fetch”。

【问题讨论】:

  • 向我们展示代码,并解释如何检查集合是否被急切/懒惰地获取。
  • 请在我原来的问题中查看更多内容

标签: hibernate lazy-loading eager-loading


【解决方案1】:

不要使用调试器来测试对象是否已初始化。调试器会在你背后调用你对象的方法,显示对象的内容,调用这些方法会初始化对象。

使用Hibernate.isInitialized(question.getSection()) 测试会话是否已初始化。

【讨论】:

  • 您可能打算使用 question.getSection() 而不是 getSession()?我用 getQuestion()、getSession() 和 getSection().getDefinitions() 进行了测试。我分别得到“真”、“假”、“假”。感谢您指出我最好不要对这些东西使用调试器。还有其他可能性可以用于这种事情吗?
  • 是的,我就是这个意思。对困惑感到抱歉。我不知道。 Hibernate.isInitialized 正是为此而生的。
猜你喜欢
  • 1970-01-01
  • 2023-03-28
  • 1970-01-01
  • 1970-01-01
  • 2014-03-03
  • 1970-01-01
  • 1970-01-01
  • 2022-11-16
  • 1970-01-01
相关资源
最近更新 更多