В чем разница между LocalContainerEntityManagerFactoryBean и LocalEntityManagerFactoryBean?

Может ли кто-нибудь объяснить, в чем разница между LocalContainerEntityManagerFactoryBean Spring Framework и LocalEntityManagerFactoryBean?


person BlueSky    schedule 27.05.2011    source источник


Ответы (8)


По сути, спецификация JPA определяет два типа менеджеров сущностей. Это:

i) Управляемый приложением: Диспетчер сущностей, управляемый приложением, означает, что «Менеджеры сущностей создаются и управляются только приложением (т. Е. Нашим кодом)».

ii) Контейнер, управляемый: Контейнер Управляемый диспетчер сущностей означает, что «диспетчеры сущностей создаются и управляются только контейнером J2EE (т. е. наш код не управляет напрямую, вместо этого диспетчеры сущностей создаются и управляются контейнером, а наши код получает EM каким-то образом, как при использовании JNDI).

Примечание. Создано и управляется (см. Выше) означает «открытие, закрытие и вовлечение менеджера объекта в транзакции».

LocalContainerEntityManagerFactoryBean - управляемый контейнером
LocalEntityManagerFactoryBean - управляемый приложением

Большое примечание: для приложений на основе Spring разница невелика. Spring играет только роли (как контейнер, если вы настроили LocalContainerEntityManagerFactoryBean, и как приложение, если вы настроили LocalEntityManagerFactoryBean < / em>)

person Prashanth    schedule 18.03.2014

В документации сказано все:

LocalContainerEntityManagerFactoryBeanager По ссылке: FactoryBean, который создает JPA EntityManagerFactory в соответствии со стандартным контрактом начальной загрузки контейнера JPA.

LocalEntityManagerFactoryBean - По ссылке: FactoryBean, который создает JPA EntityManagerFactory в соответствии со стандартным контрактом автономной начальной загрузки JPA.

По сути, разница только в том, как они создают JPA EntityManagerFactory.

person nicholas.hauschild    schedule 27.05.2011
comment
Я все еще путаю контейнер и автономный вариант. Любую ссылку, которую я могу прочитать? - person huahsin68; 21.11.2013
comment
@ huahsin68 Может быть, этот ответ прольет вам немного света: stackoverflow.com/a/28998110/814702 - person informatik01; 14.11.2016

LocalEntityManagerFactoryBean

самый простой и самый ограниченный. Вы не можете ссылаться на существующее определение bean-компонента JDBC DataSource, и не существует поддержки глобальных транзакций.

LocalContainerEntityManagerFactoryBean

- это самый мощный вариант настройки JPA, позволяющий гибко настраивать локальную конфигурацию в приложении. Он поддерживает ссылки на существующий источник данных JDBC, поддерживает как локальные, так и глобальные транзакции.

ССЫЛКА: spring-framework-reference.pdf «Весна 3»

person Bassem Reda Zohdy    schedule 23.10.2011

LocalEntityManagerFactoryBean создает объект EntityManagerFactory, управляемый приложением.

LocalContainerEntityManagerFactoryBean создает объект EntityManagerFactory, управляемый контейнером.

Ссылка: Весна в действии - Крейг Уоллс

person Chandana    schedule 23.10.2011

Спецификация JPA определяет два типа менеджеров сущностей:

  • Управляемые приложением - менеджеры объектов создаются, когда приложение напрямую запрашивает их у фабрики менеджеров объектов. В случае менеджеров объектов, управляемых приложением, приложение отвечает за открытие или закрытие менеджеров объектов и вовлечение менеджера объектов в транзакции. Этот тип диспетчера сущностей наиболее подходит для использования в автономных приложениях, которые не работают в контейнере Java EE.

  • Управляемые контейнером - менеджеры объектов создаются и управляются контейнером Java EE. Приложение вообще не взаимодействует с фабрикой менеджеров сущностей. Вместо этого менеджеры сущностей получаются напрямую через инъекцию или из JNDI. Контейнер отвечает за настройку фабрик менеджеров сущностей. Этот тип диспетчера сущностей наиболее подходит для использования контейнером Java EE, который хочет сохранить некоторый контроль над конфигурацией JPA сверх того, что указано в persistence.xml.

Управляемые приложением EntityManagers создаются EntityManagerFactory, полученным путем вызова createEntityManagerFactory() метода PersistenceProvider. Между тем, управляемые контейнером EntityManagerFactorys можно получить с помощью createContainerEntityManagerfactory()method PersistenceProvider.

Каждый вид объекта entity manager factory создается соответствующим заводским bean-компонентом Spring:

  • LocalEntityManagerFactoryBean создает управляемую приложением Entity-ManagerFactory.

  • LocalContainerEntityManagerFactoryBean создает объект EntityManagerFactory, управляемый контейнером

Важно отметить, что выбор между управляемым приложением EntityManagerFactory и управляемым контейнером EntityManagerFactory полностью прозрачен для приложения на основе Spring. Когда вы работаете со Spring и JPA, сложные детали работы с любой формой EntityManagerFactory скрыты, оставляя ваш код доступа к данным, чтобы сосредоточиться на его истинной цели: доступе к данным.

Единственная реальная разница между управляемыми приложением и управляемыми контейнером фабриками диспетчеров сущностей, насколько это касается Spring, заключается в том, как каждая из них настроена в контексте приложения Spring.

person Pra_A    schedule 18.08.2016
comment
Было бы неплохо упомянуть источник: Spring в действии. - person informatik01; 14.11.2016

  • Обе реализации LocalEntityManagerFactoryBean и LocalContainerEntityManagerFactoryBean возвращают ссылку на EntityManagerFactory из org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.
  • Каждая реализация будет использовать транзакцию resource_local, если мы явно не попросим Spring использовать JTA.
  • Основное различие между двумя реализациями заключается в том, что LocalContainerEntityManagerFactoryBean обеспечивает программную настройку единицы сохраняемости (источник данных и packageToScan), является более гибким, поскольку мы можем переопределить расположение файла persistence.xml по сравнению с LocalEntityManagerFactoryBean, в котором мы должны использовать предопределенное постоянство имени. .xml

Если оба используют resource_local по умолчанию, то не учитывается правило, что LocalContainerEntityManagerFactoryBean использует транзакцию, управляемую контейнером, а другой - транзакцию, управляемую приложением.

При использовании JPA вне контейнера внедрения зависимостей разработчик должен программно обрабатывать транзакции. Если вы используете JPA внутри контейнера для инъекций зависимостей Spring, тогда это может обрабатываться контейнером 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>

Обе реализации могут использоваться в рамках транзакции, управляемой контейнером, пожалуйста, поправьте меня, если потребуется какое-то исправление.

person Pushpendra    schedule 09.02.2019
comment
В 1-м примере после ЭДС есть ложный символ}. 2nd вводит em, но использует несуществующую emf для создания другой внутренней em. 3-й вводит ЭДС, но использует несуществующую ЭМ. - person Daniel; 05.05.2021

Чтобы использовать JPA в проекте Spring, нам нужно настроить EntityManager.

Это основная часть конфигурации, и мы можем сделать это с помощью фабричного компонента Spring. Это может быть более простой LocalEntityManagerFactoryBean или более гибкий LocalContainerEntityManagerFactoryBean.

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

person SumiSujith    schedule 27.06.2021

LocalEntityManagerFactoryBean создает EntityManagerFactory через PersistenceProvider.createEntityManagerFactory ()

LocalContainerEntityManagerFactoryBean создает EntityManagerFactory через PersistenceProvider.createContainterEntityManagerFactory ()

person Evgeniy Dorofeev    schedule 25.11.2018