【问题标题】:hibernate : org.hibernate.LazyInitializationException: failed to lazily initialize a collection of role: no session or session was closed休眠:org.hibernate.LazyInitializationException:无法延迟初始化角色集合:没有会话或会话已关闭
【发布时间】:2014-08-31 13:56:20
【问题描述】:

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

当来源如下

    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;

}

TestItem.java

@Entity
@Table ( name = "table_item" )
public class TestItem
{

    @ManyToOne(fetch=FetchType.LAZY)
    @JoinColumn(name="test_id", insertable=false, updatable=false)
    public Test parent;

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

}

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;
    }

}

TestController.java

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

    @RequestMapping ( "/{id}" )
    public String seriesList ( @PathVariable long id, Model model )
    {
        Test test = testService.get( id );

        //something...

        List<TestItem> lists = testService.getItems( test );

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

        return "index";
    }
}

例外

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)

如果我使用 Lazy.

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

我知道如何解决一些问题。

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;
    }

}

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";
    }

}

似乎有几个问题。

所以,我只想在需要时提出。

【问题讨论】:

标签: java spring hibernate session


【解决方案1】:

您需要了解会话和会话边界的概念。 Hibernate 出于性能原因使用代理,除非需要它们,否则不会加载所有关联。 Session 概念可以看here

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

【讨论】:

    猜你喜欢
    • 2011-12-11
    • 1970-01-01
    • 2014-11-02
    • 1970-01-01
    • 2015-07-02
    • 1970-01-01
    • 1970-01-01
    • 2018-02-25
    • 2011-03-31
    相关资源
    最近更新 更多