Hibernate 数据获取类型问题

Hibernate data fetch type issues

我会这样解释场景:

我有一个数据库,其中有一些 tables

  1. Activity
  2. 运动
  3. 领悟[​​=67=]
  4. 问题
  5. 句子

这里是描述关系的最佳方式,

  1. Activity 有一组练习。
  2. 练习有一组问题。
  3. 每个练习都有一个理解
  4. 每个问题都有一组句子。

这是我尝试在休眠中实现的方式:

    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 或在视图中打开会话(视图中的事务)都是不好的做法。**

如果我使用 Join 查询,我认为它在两个方面违反了:

  1. 如果数据库很大,我们有几个 table 要加入,在我的场景中,根据我的理解,我将不得不加入

    Activity 锻炼 理解 问题 句子 .........

和更多 tables,如果我必须在单连接查询中做。 2. 它不会破坏每个查询 会话 吗? ,我们在单个会话中要求太多。作为 jdbc 用户,我曾经触发单个 SQL 查询来逐一获取所有内容。一个连接将帮助我获取一个 table 数据。 3. 如果这是正确的,那么所有企业应用程序都需要加入 n 个 tables 才能使用休眠和集合,这显然是最糟糕的事情。

所以,最后,问题出现了,我该如何处理这种情况。什么是最佳实践。我问过一个人,他是这样说的

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 来设置整个数据并在应用程序范围内使用吗?这种方式还有其他好的选择吗?

session-per-query 是一个反模式。您应该:

  • 每笔交易使用一个会话
  • 在多个事务上延长会话

如果您有一个带有 multiple children levels 的根实体,您需要颠倒查询并从最内层的子实体获取到根实体:

select q
from Question q
join fetch q.exercise e
join fetch e.activity a
where a.id = :activityId

此查询将毫无疑问地过滤掉 activities/exercises,但这在您的用例中可能没问题。