【问题标题】:JPA EntityManager, how does it work?JPA EntityManager,它是如何工作的?
【发布时间】:2010-11-26 07:05:27
【问题描述】:

很抱歉这个菜鸟问题,但我在使用 JPA+Hibernate 时遇到了问题,所以我认为我脑子里有一些不清楚的地方。 我有一些实体,比如 A、B、C、D,我编写了 AMethods、BMethods、CMethods、DMethods。每个 *Methods 类都包含通过 EntityManagerFactory 初始化的 EntityManager 和一些基本上执行查询的方法。我不知道我是否应该使用单例模式(这样我每个 *Method 类都有一个 EntityManager),或者我是否需要在每次执行查询或持久/删除实体时打开和关闭 EntityManager...你能帮帮我吗?

【问题讨论】:

    标签: hibernate jpa entitymanager


    【解决方案1】:

    我希望这张照片能回答你的问题。

    【讨论】:

      【解决方案2】:

      在典型的 JPA/Hibernate 应用程序中,您不会将持久性逻辑放在实体类本身中。与较旧的 EJB 2.x 应用程序相比,这是设计理念的一个重大变化。相反,许多应用程序创建了一层数据访问对象——与实体分开——使用 EntityManager 实例来查询、加载和保存实体。通常,这些是单例,DAO 中的实体管理器实例是线程本地的。

      如果您使用像 Spring 这样的框架,EntityManager 实例和事务的管理是完全自动的。与 EJB 3 相同,尽管我没有在大型项目中使用它。我建议阅读 Spring 文档中关于 Object-Relational Mapping 数据访问的章节。即使您最终没有在应用程序中使用 Spring,本章也提供了一些关于如何以分层方式构建应用程序的好技巧,将持久性关注点与被持久化的实体分开。祝你好运!

      【讨论】:

      • 我不使用 Spring,我使用的是 DAO,正如解释的那样(DAO 是 *Methods 类),但它们都使用相同的持久性上下文。在 AMethods 和 BMethods 中执行 createEntityManager 是正确的,即使它们使用相同的持久性上下文??
      【解决方案3】:

      就这样!

      公共接口 ProtokollDAOService {

      /**
       * Fügt ein Protokollobjekt in die Datenbank hinzu.
       * 
       * @param object
       */
      public void addProtokoll (ProtokollModel object);
      
      /**
       * Läd aus einer Datenbank Protokoll-Elemente und fügt sie in eine Liste hinzu
       * 
       * @return List <ProtokollModel> Liste mit Protokoll-Elementen 
       */
      public List <ProtokollModel> getProtokolls ();
      
      /**
       * Liefert ein Protokoll-Element aus der Datenbank anhand der ID; 
       * 
       * @param id
       * @return ProtokollModel Protokoll-Element 
       */
      public ProtokollModel getProtokollById (long id);
      
      /**
       * Liefert eine Liste von Protokoll-Elementen anhand des Problem-Status 
       * 
       * @param solved
       * @return List <ProtokollModel> Liste mit Protokoll-Elementen   
       */
      public List <ProtokollModel> getProtokollByProblemStatus (boolean solved);
      
      /**
       * Liefert eine Liste von Protokoll-Elementen anhand des Aufgaben-Status 
       * 
       * @param ready
       * @return List <ProtokollModel> Liste mit Protokoll-Elementen
       */
      public List <ProtokollModel> getProtokollByAufgabenStatus (boolean ready);
      
      /**
       * Liefert ein Protokoll-Element anhand des Problems
       * 
       * @param problem
       * @return List <ProtokollModel> Liste mit Protokoll-Elementen   
       */
      public List <ProtokollModel> getProtokollByProblem (String problem);
      
      /**
       * Liefert ein Protokoll-Element anhand der Aufgabe
       * 
       * @param aufgabe
       * @return List <ProtokollModel> Liste mit Protokoll-Elementen
       */
      public List <ProtokollModel> getProtokollByAufgabe (String aufgabe);
      
      /**
       * Ausgabe der Protokoll-Tabelle
       * 
       */
      public void printTable ();
      

      }

      公共类 ProtokollDAOImpl 实现 ProtokollDAOService { 私有静态最终字符串 PERSISTENCE_UNIT_NAME = "ProtokollManager"; 私有 EntityManagerFactory 实体工厂;

      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#addProtokoll(model.ProtokollModel)
       */
      public void addProtokoll(ProtokollModel object) {
          try
          {
              entityFactory = Persistence
                      .createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
              EntityManager em = entityFactory.createEntityManager();
      
              // Transaction starten
              em.getTransaction().begin();
      
              // Object zum speichern
              em.persist(object);
      
              // commit senden an die DB / Transaction abschliessen
              em.getTransaction().commit();
      
              // DB connection schliessen
              em.close();
          }
          catch (Exception e)
          {
              Logger.console("Exception wurde ausgelösst! " + e);
              e.printStackTrace();
          }
      }
      
      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#getProtokollByAufgabe(java.lang.String)
       */
      public List<ProtokollModel> getProtokollByAufgabe(String aufgabe) {
          // TODO Auto-generated method stub
          return null;
      }
      
      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#getProtokollByAufgabenStatus(boolean)
       */
      public List<ProtokollModel> getProtokollByAufgabenStatus(boolean ready) {
          // TODO Auto-generated method stub
          return null;
      }
      
      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#getProtokollById(long)
       */
      public ProtokollModel getProtokollById(long id) {
          try
          {
              entityFactory = Persistence
                      .createEntityManagerFactory(PERSISTENCE_UNIT_NAME);
              EntityManager em = entityFactory.createEntityManager();
      
              // Transaction starten
              em.getTransaction().begin();
      
              // Object aus der DB laden
              Query q = em.createQuery("select m from ProtokollModel m where m.id=:id");
      
              // Parameter setzen - siehe PreparedStatment
              q.setParameter("id", id);
      
              // liefert das Protokoll-Element zurück 
              ProtokollModel pm = (ProtokollModel) q.getSingleResult();
      
              // commit senden an die DB / Transaction abschliessen
              em.getTransaction().commit();
      
              // db connection schliessen
              em.close();
      
              return pm;
          }
          catch (Exception e)
          {
              Logger.console("Exception wurde ausgelösst! " + e);
              e.printStackTrace();
          } finally {
      
          }
      
          return null;
      }
      
      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#getProtokollByProblem(java.lang.String)
       */
      public List<ProtokollModel> getProtokollByProblem(String problem) {
          // TODO Auto-generated method stub
          return null;
      }
      
      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#getProtokollByProblemStatus(boolean)
       */
      public List<ProtokollModel> getProtokollByProblemStatus(boolean solved) {
          // TODO Auto-generated method stub
          return null;
      }
      
      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#getProtokolls()
       */
      public List<ProtokollModel> getProtokolls() {
          // TODO Auto-generated method stub
          return null;
      }
      
      /*
       * (non-Javadoc)
       * 
       * @see util.ProtokollDAOService#printTable()
       */
      public void printTable() {
          // TODO Auto-generated method stub
      }
      

      }

      【讨论】:

        【解决方案4】:

        EntityManager 与持久化上下文相关联。如果您的所有实体都与一个上下文相关联,请使用单例模式。 您在服务器端使用 jpa,对吗?如果是这样,您可以在 init 方法中初始化 EntityManager,例如 servlet 上的 init()。

        【讨论】:

        • 我使用相同的持久化上下文,每个实体都与一个上下文相关联。我在服务器端使用 jpa,但我也在后台运行的 java 应用程序中使用它...我应该在这个应用程序中初始化上下文并创建 *Methods 将 EntityManager 作为参数传递??
        • 是的,如果服务和您的后台应用程序是不同的应用程序,则有必要为两者启动 EntityManager。我认为序列化 EntityMaanger 实例将是一项艰巨的任务。
        • 使用 Spring,使用 Hibernate。为什么选择 Ejb?
        • 我只是按照此处的说明使用了 JPA:java.sun.com/javaee/5/docs/tutorial/doc/bnbpz.html。我的方法有问题吗?
        • JPA 像驱动程序一样用作 ORM 的下划线。为什么不使用没有任何抽象的 ORM?
        猜你喜欢
        • 1970-01-01
        • 2012-02-10
        • 2020-11-26
        • 1970-01-01
        • 1970-01-01
        • 2023-03-23
        • 2018-01-20
        • 2013-04-22
        • 1970-01-01
        相关资源
        最近更新 更多