LocalContainerEntityManagerFactoryBean和LocalEntityManagerFactoryBean有什么区别?

时间:2011-05-27 19:28:45

标签: spring hibernate jpa entitymanager spring-orm

有人可以解释Spring Framework的 LocalContainerEntityManagerFactoryBean LocalEntityManagerFactoryBean 之间的区别吗?

8 个答案:

答案 0 :(得分:32)

基本上 JPA规范定义了 两种类型的实体管理器 。它们是:

i)应用程序管理:应用程序托管实体管理器意味着"实体管理器仅由应用程序(即我们的代码)创建和管理" 。

ii)Container Managed:容器管理实体管理器意味着"实体管理器仅由J2EE容器创建和管理(即我们的代码不直接管理实体管理器是由容器创建和管理,我们的代码通过使用JNDI等方式获得EM。

注意:创建和管理(上述)意味着"在交易中打开,关闭和涉及实体经理"

LocalContainerEntityManagerFactoryBean - 容器管理
LocalEntityManagerFactoryBean - 应用程序托管

大注: 对于基于Spring的应用程序,差别不大 Spring仅扮演角色(如果配置 LocalContainerEntityManagerFactoryBean ,则为容器;如果配置 LocalEntityManagerFactoryBean,则为应用程序 < / em>的)

答案 1 :(得分:16)

文档说明了一切:

LocalContainerEntityManagerFactoryBean - 来自链接:FactoryBean,它根据JPA的标准容器引导程序合同创建JPA EntityManagerFactory。

LocalEntityManagerFactoryBean - 来自链接:FactoryBean,它根据JPA的标准独立引导合同创建JPA EntityManagerFactory。

基本上,唯一的区别在于他们如何创建JPA EntityManagerFactory

答案 2 :(得分:16)

LocalEntityManagerFactoryBean负责

是最简单和最有限的。您不能引用现有的JDBC 存在DataSource bean定义并且不支持全局事务。

LocalContainerEntityManagerFactoryBean

是最强大的JPA设置 选项,允许在应用程序内进行灵活的本地配置。它支持指向现有JDBC DataSource的链接,支持本地和全局事务

REF:spring-framework-reference.pdf“Spring 3”

答案 3 :(得分:10)

LocalEntityManagerFactoryBean生成应用程序管理的EntityManagerFactory。

LocalContainerEntityManagerFactoryBean生成容器管理的 EntityManagerFactory的。

参考:Spring In Action - Craig Walls

答案 4 :(得分:5)

JPA规范定义了两个 各种实体经理:

  • 应用程序管理 - 直接在应用程序中创建实体经理 从实体经理工厂请求一个。使用应用程序管理的实体 经理,该应用程序负责开立或关闭实体经理 并让实体经理参与交易。这种类型的实体管理器是 最适合在不在Java EE中运行的独立应用程序中使用 容器

  • 容器管理 -Entity管理器由Java EE创建和管理 容器。该应用程序不与实体管理器工厂交互 所有。相反,实体经理是通过注入或直接获得的 JNDI。容器负责配置实体管理器工厂。 这种类型的实体管理器最适合Java EE容器使用 希望保持对JPA配置的某些控制,超出persistence.xml中指定的范围。

应用程序管理 EntityManagers由通过调用PersistenceProvider的EntityManagerFactory方法获得的createEntityManagerFactory()创建。同时,容器管理的 EntityManagerFactorys是通过PersistenceProvider的createContainerEntityManagerfactory()方法获得的。

实体管理器工厂的每种风格都由相应的Spring工厂bean生成:

  • LocalEntityManagerFactoryBean生成应用程序管理的实体 - ManagerFactory。

  • LocalContainerEntityManagerFactoryBean生成容器管理 EntityManagerFactory的

重要的是要指出在应用程序管理之间做出的选择 EntityManagerFactory和容器管理的EntityManagerFactory对基于Spring的应用程序完全透明。当您使用Spring和JPA时,处理任何形式的EntityManagerFactory的复杂细节都会被隐藏,让您的数据访问代码专注于其真正的目的:数据访问。

就Spring而言,应用程序管理的容器管理的实体管理器工厂之间唯一真正的区别在于它们是如何在Spring应用程序上下文中配置的。

答案 5 :(得分:0)

LocalEntityManagerFactoryBean通过PersistenceProvider.createEntityManagerFactory()创建EntityManagerFactory

LocalContainerEntityManagerFactoryBean通过PersistenceProvider.createContainterEntityManagerFactory()创建EntityManagerFactory

答案 6 :(得分:0)

  • 两个实现LocalEntityManagerFactoryBean和 LocalContainerEntityManagerFactoryBean返回EntityManagerFactory 参考来自 org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl。
  • 每个实现都将使用resource_local事务,除非我们 明确要求Spring使用JTA。
  • 两个实现之间的主要区别是 LocalContainerEntityManagerFactoryBean以编程方式提供 设置持久性单元(数据源和packageToScan),更多 灵活的是,我们可以覆盖persistence.xml的位置 文件与LocalEntityManagerFactoryBean相比,在其中我们必须使用预定义名称persistence.xml

如果两者都使用resource_local作为默认值,那么就不会忽略LocalContainerEntityManagerFactoryBean正在使用容器管理的事务而其他正在使用应用程序管理的事务的规则。

在依赖项注入容器之外使用JPA时,开发人员需要以编程方式处理事务。如果在Spring依赖项注入容器中使用JPA,则可以由Spring容器处理。

使用LocalContainerEntityManagerFactoryBean的示例

public class DataConfig {
    @Bean
    LocalContainerEntityManagerFactoryBean entityManagerFactory() {
        //LocalEntityManagerFactoryBean lfb = new LocalEntityManagerFactoryBean();
        LocalContainerEntityManagerFactoryBean lfb = new LocalContainerEntityManagerFactoryBean();
        lfb.setDataSource(dataSource());
        lfb.setPersistenceUnitName("localEntity");
        lfb.setPersistenceProviderClass(HibernatePersistence.class);
        lfb.setPackagesToScan("com.javasampleapproach.h2database.model");
        lfb.setJpaProperties(hibernateProps());
        return lfb;
    }
}
@Component
public class PostRepository {
  @Autowired
    EntityManagerFactory emf;
  }
  public void create(){
      EntityManager em = emf.createEntityManager();
      Post post = new Post("First post");
      em.getTransaction().begin();
      em.persist(post);
      em.getTransaction().commit();
  }
}

LocalEntityManagerFactoryBean错误

java.lang.IllegalStateException:不允许在共享EntityManager上创建事务-改为使用Spring事务或EJB CMT

public class DataConfig {
    @Bean
    LocalEntityManagerFactoryBean entityManagerFactory() {
        LocalEntityManagerFactoryBean lfb = new LocalEntityManagerFactoryBean();
        lfb.setPersistenceUnitName("localEntity");
        lfb.setPersistenceProviderClass(HibernatePersistence.class);
        lfb.setJpaProperties(hibernateProps());
        return lfb;
    }
}

@Component
    public class PostRepository {
      @Autowired
      EntityManager em;

      public void create(){
          EntityManager em = emf.createEntityManager();
          Post post = new Post("First post");
          em.getTransaction().begin();
          em.persist(post);
          em.getTransaction().commit();
      }
    }
<persistence-unit name="localEntity">
</persistence-unit>

使用LocalEntityManagerFactoryBean的工作代码

Spring管理的事务,例如LocalEntityManagerFactoryBean的容器管理的事务。

public class DataConfig {
    @Bean
    LocalEntityManagerFactoryBean entityManagerFactory() {
        LocalEntityManagerFactoryBean lfb = new LocalEntityManagerFactoryBean();
        lfb.setPersistenceUnitName("localEntity");
        lfb.setPersistenceProviderClass(HibernatePersistence.class);
        lfb.setJpaProperties(hibernateProps());
        return lfb;
    }
}

@Component
public class PostRepository {
  @Autowired
  EntityManagerFactory emf;

  @Transactional
  public void create() {
    Post post = new Post("First post");
    em.persist(post);
  }
}

<persistence-unit name="localEntity">
</persistence-unit>

这两个实现都可以在容器管理的事务下使用,如果需要一些更正,请对此进行更正。

答案 7 :(得分:0)

要在 Spring 项目中使用 JPA,我们需要设置 EntityManager。

这是配置的主要部分,我们可以通过 Spring factory bean 来完成。 这可以是更简单的 LocalEntityManagerFactoryBean 或更灵活的 LocalContainerEntityManagerFactoryBean

baeldung.com/the-persistence-layer-with-spring-and-jpa