我会解释这样的情景:
我有一个数据库,其中包含一些表格
描述关系的最佳方式是
这是我尝试在hibernate中实现的方式:
public Exercise getActivityById(int ActivityId)
{
Session session = HibernateUtil.getSessionFactory().openSession();
Activity a = (Activity)session.get(Activity.class, ActivityId);
session.close();
return a;
}
public List<Exercise> getExercisesFromActivity(Activity a)
{
Session session = HibernateUtil.getSessionFactory().openSession();
List<Exercise> e = a.getExercises();
session.close();
return e;
}
public Comprehension getComprehensionFromExercise(Exercise e)
{
Session session = HibernateUtil.getSessionFactory().openSession();
Comprehension c = e.getComprehension();
session.close();
return c;
}
//...... and so on
// i will call like this
Activity a = getActivityById(23);
List<Exercise> e = a.getExercisesFromActivity(a);
Comprehension c = getComprehension(e.get(0));
//.... and so on
基本上,我正在尝试遵循每个查询的会话的最佳做法。在这种方法中,我得到了异常LazyInitializationException ,因为该对象已经被分离。
所以,我搜索了一切并发现,我可以尝试4个解决方案,我在多个网站上找到了相同的东西。
http://uaihebert.com/four-solutions-to-the-lazyinitializationexception/
其中,如果我尝试制作** default-lazy = false ,或者在View中打开会话(在视图中进行交易),这两种做法都是不好的做法。**
如果我使用加入查询,我认为它违反了两种方式:
如果数据库非常庞大,我们有几个表要加入,在我的场景中,根据我的理解,我将不得不加入
活动 行使 理解 题 句子 .........
以及更多表,如果我必须在单个连接查询中执行。 2. Dosen`t voilate 会话每个查询? ,我们在单一会议上要求太多。作为一个jdbc用户,我曾经使用单个SQL查询来逐个获取每个查询。一个连接将帮助我获取一个表数据。 3.如果这是正确的,那么所有企业应用程序都需要加入n个表来处理hibernate和集合,这显然是最糟糕的事情。
所以,最后,问题出现了,我该如何处理这种情况。什么是最好的做法。我问过一个人他说过这样的话
public void getEverything()
{
Session session = HibernateUtil.getSessionFactory().openSession();
Activity a = (Activity)session.get(Activity.class, ActivityId);
List<Exercises> e = a.getExercises();
Comprehension c = e.get(0).getComprehension();
List<Question> q = e.get(0).getQuestions();
ApplicationWidePojo apojo = new ApplicationWidePojo();
// set all the tables , values in this pojo
session.close
}
// this eliminated lazyinitializationexception
但我认为不是每个查询的会话。或细粒度
此外,还有一个问题。我应该使用一个pojo来设置整个数据并使用应用程序吗?这种方式的任何其他好的替代方案?
答案 0 :(得分:1)
session-per-query是一种反模式。你应该:
如果您的根实体具有multiple children levels,则需要将查询颠倒并从最内层的子级获取到Root实体:
select q
from Question q
join fetch q.exercise e
join fetch e.activity a
where a.id = :activityId
此查询将毫无疑问地过滤掉活动/练习,但在您的用例中可能没问题。