What is the difference between LocalContainerEntityManagerFactoryBean and LocalEntityManagerFactoryBean?

后端 未结 7 526
离开以前
离开以前 2020-12-24 01:45

Can anybody explain what is the difference between the Spring Framework\'s LocalContainerEntityManagerFactoryBean and LocalEntityManagerFactoryBean?

相关标签:
7条回答
  • 2020-12-24 01:51
    • Both implementations LocalEntityManagerFactoryBean and LocalContainerEntityManagerFactoryBean returns EntityManagerFactory reference from org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.
    • Each implementation will use resource_local transaction unless we explicitly ask Spring to use JTA.
    • A major difference between the two implementations is LocalContainerEntityManagerFactoryBean provide programmatically setting persistence unit (data source & packageToScan), is more flexible in that we can override the location of the persistence.xml file compare to LocalEntityManagerFactoryBean in which we have to use a predefined name persistence.xml

    If both are using resource_local as default then it does not thumb rule that LocalContainerEntityManagerFactoryBean is using container-managed transaction and other is using application-managed transaction.

    When using JPA outside of a dependency injection container, transactions need to be handled programmatically by the developer. If using JPA inside of Spring dependency injection container then it can be handled by Spring container.

    Example using 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();
      }
    }
    

    Error with LocalEntityManagerFactoryBean

    java.lang.IllegalStateException: Not allowed to create a transaction on shared EntityManager - use Spring transactions or EJB CMT instead

    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>
    

    Working code with LocalEntityManagerFactoryBean

    Spring managed transaction like container-managed in case of 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>
    

    Both implementations can be used under container-managed transaction, please correct me on this if some correction is need.

    0 讨论(0)
  • 2020-12-24 01:53

    The JPA specification defines two kinds of entity managers:

    • Application-managed—Entity managers are created when an application directly requests one from an entity manager factory. With application-managed entity managers, the application is responsible for opening or closing entity managers and involving the entity manager in transactions. This type of entity manager is most appropriate for use in standalone applications that don’t run in a Java EE container.

    • Container-managed—Entity managers are created and managed by a Java EE container. The application doesn’t interact with the entity manager factory at all. Instead, entity managers are obtained directly through injection or from JNDI. The container is responsible for configuring the entity manager factories. This type of entity manager is most appropriate for use by a Java EE container that wants to maintain some control over JPA configuration beyond what’s specified in persistence.xml.

    Application-managed EntityManagers are created by an EntityManagerFactory obtained by calling the createEntityManagerFactory() method of the PersistenceProvider. Meanwhile, container-managed EntityManagerFactorys are obtained through PersistenceProvider’s createContainerEntityManagerfactory()method.

    Each flavor of entity manager factory is produced by a corresponding Spring factory bean:

    • LocalEntityManagerFactoryBean produces an application-managed Entity- ManagerFactory.

    • LocalContainerEntityManagerFactoryBean produces a container-managed EntityManagerFactory

    It’s important to point out that the choice made between an application-managed EntityManagerFactory and a container-managed EntityManagerFactory is completely transparent to a Spring-based application. When you’re working with Spring and JPA, the intricate details of dealing with either form of EntityManagerFactory are hidden, leaving your data-access code to focus on its true purpose: data access.

    The only real difference between application-managed and container-managed entity manager factories, as far as Spring is concerned, is how each is configured in the Spring application context.

    0 讨论(0)
  • 2020-12-24 01:57

    The documentation says it all:

    LocalContainerEntityManagerFactoryBean -- From the link: FactoryBean that creates a JPA EntityManagerFactory according to JPA's standard container bootstrap contract.

    LocalEntityManagerFactoryBean -- From the link: FactoryBean that creates a JPA EntityManagerFactory according to JPA's standard standalone bootstrap contract.

    Essentially, the only difference is in how they create the JPA EntityManagerFactory.

    0 讨论(0)
  • 2020-12-24 02:00

    LocalEntityManagerFactoryBean creates EntityManagerFactory via PersistenceProvider.createEntityManagerFactory()

    LocalContainerEntityManagerFactoryBean creates EntityManagerFactory via PersistenceProvider.createContainterEntityManagerFactory()

    0 讨论(0)
  • 2020-12-24 02:01

    LocalEntityManagerFactoryBean produces an application-managed EntityManagerFactory.

    LocalContainerEntityManagerFactoryBean produces a container-managed EntityManagerFactory.

    Ref : Spring In Action - Craig Walls

    0 讨论(0)
  • 2020-12-24 02:11

    Basically JPA specification defines two types of entity managers. They are :

    i) Application-Managed : Application Managed entity manager means "Entity Managers are created and managed by merely the application ( i.e. our code )" .

    ii) Container Managed : Container Managed entity manager means "Entity Managers are created and managed by merely the J2EE container ( i.e. our code doesn't directly manages instead entity managers are created and managed by container , and our code gets EM's through some way like using JNDI ).

    Note : Created and Managed (above) means "opening , closing and involving entity manager in transactions"

    LocalContainerEntityManagerFactoryBean - container managed
    LocalEntityManagerFactoryBean - application managed

    A Big Note : For spring based applications, the difference is not much. Spring only plays roles ( as container if you configure LocalContainerEntityManagerFactoryBean and as application if you configure LocalEntityManagerFactoryBean)

    0 讨论(0)
提交回复
热议问题