2014-08-31 86 views
3

我學習了休眠。 但我被困在一個非常基本的點。hibernate:org.hibernate.LazyInitializationException:無法懶惰地初始化一個角色集合:沒有會話或會話被關閉

當以下

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

EXCEPTION

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) 

我若用懶惰什麼原因。

這是因爲它可能不被「Something」列表使用。

我知道如何解決一些問題。

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

} 

似乎有幾個問題上運行。

所以,我只想在需要時調出。

+0

請閱讀http://www.javacodegeeks.com/2012/07/four-solutions-to-lazyinitializationexc_05.html – sol4me 2014-08-31 05:48:51

回答

1

您需要了解會話和會話邊界的概念。爲了性能的原因,Hibernate與代理協同工作,除非需要,否則不會加載所有關聯。對於會話概念,你可以看到here

如果你在Spring環境中(我認爲你是),你可能想檢查打開會話過濾器。這將在請求的上下文中打開一個會話,以便您可以訪問所有層中的關聯。您可能不想增加事務邊界。

相關問題