【问题标题】:Intermittent Lazy exception while fetching the child entities from the projectionlist从投影列表中获取子实体时出现间歇性延迟异常
【发布时间】:2015-08-10 12:26:07
【问题描述】:

在我的 spring 项目中,当我尝试从通过 dao 层中的投影列表获取的对象中获取子实体时,间歇性地遇到 延迟初始化异常

    public class TestMapping extends PersistentEntity {

    private static final long serialVersionUID = 1L;

    private TestModel testModel = new TestModel();

    private String testMappingString;

    private String testModelCategory;

    private Boolean active;

    }

<hibernate-mapping>
    <class name="com.domain.TestModel"
        dynamic-insert="true" dynamic-update="true"
        table="ref_manufacturermodel">

        <id name="id" column="testmodelid" type="long"
            unsaved-value="-1">
            <generator class="seqhilo">
                <param name="max_lo">1</param>
                <param name="sequence">
                    testmodel_seq
                </param>
            </generator>
        </id>

        <version name="version" column="version"
            type="java.lang.Integer" unsaved-value="null" />

        <component name="auditInfo"
            class="com.domain.AuditInfo">

            <many-to-one name="createdBy"
                class="com.domain.User" cascade="none" outer-join="auto"
                update="false" insert="true" 
                column="createdby" not-null="true" />

            <property name="createdDate" type="java.util.Date"
                update="false" insert="true" column="createddate" not-null="true" />

            <property name="lastUpdatedDate" type="java.util.Date"
                update="true" insert="true" column="lastupdateddate" />

            <many-to-one name="updatedBy"
                class="com.domain.User" cascade="none" outer-join="auto"
                update="true" insert="true" 
                column="updatedby" />

        </component>

        <property name="modelNumber" type="java.lang.String"
            update="true" insert="true" column="modelnumber" not-null="true" />

        <property name="modelTitle"
            type="com.hibernate.userType.LabelUserType" update="true"
            insert="true" column="title" />

        <property name="modelCode" type="java.lang.String"
          update="true" insert="true" column="modelcode"/>

        <property name="active" type="java.lang.Boolean" not-null="true"
            update="true" insert="true" column="active" />

        <many-to-one name="model" class="com.domain.Model"
            cascade="none" update="true" insert="true" foreign-key="fk_model_modelid"
            column="modelid" />  

        .................................................
        .................................................
        .................................................

    </class>    

</hibernate-mapping>


    public class TestModel extends PersistentEntity {


     private Model model;
     ........
     ........//Number of child objects

    }


    public interface TestModelDAO extends DAO<TestModel, Long> {
       public List<TestModel> findTestModelByMapping(String testString, String tester,String testModelCategory);
    }

    public class TestModelDaoImpl extends BaseDAOImpl<TestModel, Long> implements TestModelDAO {
    @Override
    public List<TestModel> findTestModelByMapping(String testString, String tester,String testModelCategory) {
        DetachedCriteria dc = DetachedCriteria.forClass(TestMapping.class);
        dc.setProjection(Projections.property("testModel"));
        dc.createAlias("testModel", "tm");
        dc.createAlias("tm.categorytester", "cm");
        dc.createAlias("cm.category", "category");
        dc.add(Restrictions.sqlRestriction("lower(testString) in (?)", testString.toLowerCase(),
                Hibernate.STRING));
        dc.add(Restrictions.eq("testModelCategory", testModelCategory));
        return getHibernateTemplate().findByCriteria(dc);
    }
    }


    public interface TestMappingService {
        public ManufacturerModel getMappedModels();
    }


    @Service("testMappingService")
    public class TestMappingServiceImpl implements TestMappingService {
       public ManufacturerModel getMappedModels() {
        ......................
        ......................
        List<TestModel> modelList=testModelDao.findTestModelByMapping("abc", "test1", "category1");
        TestModel testModel = modelList.size()>0?modelList.get(0):null;
        Workflow workflow = testModel.getModel().getWorkflow;
        **// When i put debugger point on testmodel object it shows me the com.sun.jdi.InvocationException on the child entity *Model*. So as soon as getWorkflow is called, lazy exception is thrown. ** 
       }
    }
  1. 在我的一个服务类中,我得到了列表 上面的方法返回给我 TestModel 的列表,当我尝试 访问 TestModel 的子对象然后我得到了懒惰 日志中的初始化异常。

  2. 当我调试代码并将鼠标悬停在 TestModel 对象上时,调试器弹出窗口会显示 TestModel 对象的子对象的 com.sun.jdi.InvocationException

  3. 我不是每次都遇到这个异常。有时它会显示

不知道为什么我们会看到这种奇怪的行为。为什么为子对象显示惰性异常?有什么建议吗?

【问题讨论】:

  • 您在不同的地方加载此列表吗?可能有些地方处于开放事务中,而有些地方未处于开放事务中(LazyLoadingException)
  • 向我们展示引发异常的代码。
  • 我添加了更多细节...如果需要任何其他信息,请告诉我。

标签: java spring hibernate


【解决方案1】:

Hibernate 做的默认事情是惰性的,不加载子对象,但只在需要时才这样做。

但要使其工作,父对象必须处于持久状态,并具有活动的持久上下文。

您正在进行分离查询,因此父级处于分离状态。

您需要从 Session 对象中获取 Criteria。

【讨论】:

  • 这与 Criteria 或 detached criteria 无关,都使用当前会话。
【解决方案2】:

是你的方法,它正在操作从 DAO 返回的对象,在事务中运行。 如果没有,您可以尝试在 getMappedModels() TestMappingService 接口的方法上使用@Transactional,看看是否可以解决您的问题。

【讨论】:

  • 即使使用@Transactional,问题仍然存在
猜你喜欢
  • 2011-10-13
  • 1970-01-01
  • 2014-05-27
  • 1970-01-01
  • 1970-01-01
  • 2017-04-18
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多