Hibernate数据获取类型问题

时间:2015-02-27 07:06:27

标签: java database hibernate orm hibernate-mapping

我会解释这样的情景:

我有一个数据库,其中包含一些表格

  1. 活动
  2. 运动
  3. 理解
  4. 问题
  5. 句子
  6. 描述关系的最佳方式是

    1. 活动有一套练习。
    2. 练习有一系列问题。
    3. 每个练习都有一个理解
    4. 每个问题都有一套句子。
    5. 这是我尝试在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中打开会话(在视图中进行交易),这两种做法都是不好的做法。**

      如果我使用加入查询,我认为它违反了两种方式:

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

        活动 行使 理解 题 句子 .........

      2. 以及更多表,如果我必须在单个连接查询中执行。 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来设置整个数据并使用应用程序吗?这种方式的任何其他好的替代方案?

1 个答案:

答案 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

此查询将毫无疑问地过滤掉活动/练习,但在您的用例中可能没问题。