我正在学习冬眠。 但我陷入了一个非常基本的问题。
以下来源
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)
如果我使用懒惰是什么原因。
这是因为它可能不被列出的“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 :(得分:1)
您需要了解会话和会话边界的概念。出于性能原因,Hibernate与代理一起使用,除非需要,否则不会加载所有关联。对于会话概念,您可以看到here
如果您处于Spring环境(我认为您是),您可能需要检查Open Session过滤器。这将在请求的上下文中打开会话,以便您可以访问所有层中的关联。您可能不希望增加事务边界。