Java hibernate:org.hibernate.LazyInitializationException:延迟初始化角色集合失败:未关闭任何会话或会话

Java hibernate:org.hibernate.LazyInitializationException:延迟初始化角色集合失败:未关闭任何会话或会话,java,spring,hibernate,session,Java,Spring,Hibernate,Session,我正在学习冬眠。 但我有一个非常基本的观点 当出现以下情况时 Controller : data collection and ready to display Service : Transaction processing Dao : access Database 以及以这种形式处理数据 Test.java @Entity @Table ( name = "table_test" ) public class Test { @Id @Gen

我正在学习冬眠。 但我有一个非常基本的观点

当出现以下情况时

    Controller : data collection and ready to display 
    Service : Transaction processing
    Dao : access Database 
以及以这种形式处理数据


Test.java

@Entity
@Table ( name = "table_test" )
public class Test
{

    @Id
    @GeneratedValue ( strategy = GenerationType.AUTO )
    public long id;

    @OneToMany(fetch=FetchType.LAZY)
    @JoinColumn(name="test_id")
    @IndexColumn(name="orderBy")
    public List<TestItem> items;

}
TestDao.java

@Repository
public class TestDao
{

    @Autowired SessionFactory sessionFactory;

    protected Session getSession(){
        return sessionFactory.getCurrentSession();
    }

    public Test get(long id){
        return (Test) getSession().createCriteria( Test.class )
                    .add( Restrictions.eq( "id", id ) ).uniqueResult();
    }
}
TestService.java

@Service
@Transactional
public class TestService
{

    @Autowired
    TestDao testd;

    public Test get(long id){
        return testd.get( id );
    }

    public List<TestItem> getItems(Test test){
        List<TestItem> items = test.items;
        items.iterator();
        return items;
    }

}

如果我使用懒惰的人,原因是什么

这是因为列表中的“某物”可能不使用它

我知道如何解决一些问题

1) 第一种解决方案是“已经列出”,但不需要懒惰的人

@Service
@Transactional
public class TestService
{

    @Autowired
    TestDao testd;

    public Test get(long id){
        Test test = testd.get( id );
        test.items.iterator();
        return test;
    }

    public List<TestItem> getItems(Test test){
        List<TestItem> items = test.items;
        items.iterator();
        return items;
    }

}
@服务
@交易的
公共类测试服务
{
@自动连线
TestDao-testd;
公共测试获取(长id){
Test=testd.get(id);
test.items.iterator();
回归试验;
}
公共列表项目(测试){
列表项目=测试项目;
items.iterator();
退货项目;
}
}
2) 第二种解决方案“通过内部事务处理”,但此解决方案使用的是,始终在事务中运行

@Controller
@RequestMapping ( "/test" )
public class TestController extends BaseController
{
    @Autowired
    TestService testService;

    @RequestMapping ( "/{id}" )
    public String seriesList ( @PathVariable long id, Model model )
    {
        return testService.view( id, model );
    }
}
@Service
@Transactional
public class TestService
{

    @Autowired
    TestDao testd;

    public Test get(long id){
        Test test = testd.get( id );
        return test;
    }

    public String view(long id, Model model){
        Test test = get( id );

        List<TestItem> lists = test.items;

        for(TestItem item : lists)
        {
            model.addAttribute( item.id );
        }

        return "index";
    }

}
@控制器
@请求映射(“/test”)
公共类TestController扩展了BaseController
{
@自动连线
测试服务测试服务;
@请求映射(“/{id}”)
公共字符串序列列表(@PathVariable long id,模型)
{
返回testService.view(id,model);
}
}
@服务
@交易的
公共类测试服务
{
@自动连线
TestDao-testd;
公共测试获取(长id){
Test=testd.get(id);
回归试验;
}
公共字符串视图(长id,模型){
测试=获取(id);
列表=测试项目;
用于(测试项:列表)
{
model.addAttribute(item.id);
}
返回“索引”;
}
}

似乎有几个问题


因此,我只想在需要时提出。

您需要理解会话和会话边界的概念。出于性能考虑,Hibernate使用代理,除非需要,否则不会加载所有关联。有关会话概念,您可以看到

如果您在Spring环境中(我想您是这样),您可能需要检查Open Session filter。这将在请求上下文中打开会话,以便您可以访问所有层中的关联。您可能不想增加交易边界。

请阅读
org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: com.test.domain.Test.items, no session or session was closed
    org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationException(AbstractPersistentCollection.java:383)
    org.hibernate.collection.AbstractPersistentCollection.throwLazyInitializationExceptionIfNotConnected(AbstractPersistentCollection.java:375)
    org.hibernate.collection.AbstractPersistentCollection.initialize(AbstractPersistentCollection.java:368)
@Service
@Transactional
public class TestService
{

    @Autowired
    TestDao testd;

    public Test get(long id){
        Test test = testd.get( id );
        test.items.iterator();
        return test;
    }

    public List<TestItem> getItems(Test test){
        List<TestItem> items = test.items;
        items.iterator();
        return items;
    }

}
@Controller
@RequestMapping ( "/test" )
public class TestController extends BaseController
{
    @Autowired
    TestService testService;

    @RequestMapping ( "/{id}" )
    public String seriesList ( @PathVariable long id, Model model )
    {
        return testService.view( id, model );
    }
}
@Service
@Transactional
public class TestService
{

    @Autowired
    TestDao testd;

    public Test get(long id){
        Test test = testd.get( id );
        return test;
    }

    public String view(long id, Model model){
        Test test = get( id );

        List<TestItem> lists = test.items;

        for(TestItem item : lists)
        {
            model.addAttribute( item.id );
        }

        return "index";
    }

}