Reputation: 113
I'm learn to hibernate. But I'm stuck in a very basic point.
When the source of the following
Controller : data collection and ready to display
Service : Transaction processing
Dao : access Database
And processing data in such a form.
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)
For what reason if I use the Lazy.
This is because it may not be used by the "Something" that list.
I know how to work around some.
1) first solution is "already list", but eliminates the need for the lazy.
@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) second solution "process by inner Transaction", but this solution use, always run in transaction
@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";
}
}
There seems to have several problems.
So, I want to bring up only when needed.
Upvotes: 4
Views: 1157
Reputation: 1475
You will need to understand the concept of Session and session boundaries. Hibernate works with proxies for reason of performance and does not loads all the associations unless they are needed. For Session concepts you can see here
If you are in Spring environment (which I think you are), you might want to check Open Session filter. This opens a session in the context of a request so that you can access associations in all layers. You might not want to increase your transaction boundaries.
Upvotes: 1