从投影列表中获取子实体时出现间歇性延迟异常

时间:2015-08-10 12:26:08

标签: java spring hibernate

在我的春季项目中,当我尝试从通过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. 在我的一个服务类中,我得到了List 上面的方法返回TestModel的列表,当我尝试 访问TestModel的子对象然后我得到了懒惰 日志中的初始化异常。

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

  3. 我每次都没有得到这个例外。有时它显示
  4. 不确定为什么我们会看到这样的行为。为什么要为子项显示惰性异常?有什么建议吗?

2 个答案:

答案 0 :(得分:3)

Hibernate要做的默认操作是懒惰,而不是加载子对象,但只在需要时才这样做。

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

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

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

答案 1 :(得分:0)

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