Может кто-нибудь объяснить, в чем разница между Spring Framework LocalContainerEntityManagerFactoryBean и LocalEntityManagerFactoryBean?
В чем разница между LocalContainerEntityManagerFactoryBean и LocalEntityManagerFactoryBean?
Ответ 1
В основном, спецификация JPA определяет два типа менеджеров сущностей. Они есть:
i) Управляемый приложением : Менеджер сущностей, управляемый приложением, означает "Менеджеры сущностей создаются и управляются только приложением (т.е. нашим кодом)".
ii) Контейнер Управляемый: Диспетчер сущностей Управляемый контейнером означает, что "Менеджеры сущностей создаются и управляются просто контейнером J2EE (т.е. наш код не управляет напрямую, а менеджеры сущностей создаются и управляются контейнером, а наш код получает EM через что-то вроде используя JNDI).
Примечание: "Создан и управляем" (выше) означает "открытие, закрытие и привлечение менеджера сущностей в транзакции"
LocalContainerEntityManagerFactoryBean - управляемый контейнер
LocalEntityManagerFactoryBean - приложение управляется
Большое примечание: для пружинных приложений разница невелика. Spring только играет роли (как контейнер, если вы настраиваете LocalContainerEntityManagerFactoryBean, и как приложение, если вы настраиваете LocalEntityManagerFactoryBean)
Ответ 2
В документации написано все:
LocalContainerEntityManagerFactoryBean - по ссылке: FactoryBean, которая создает JPA EntityManagerFactory в соответствии со стандартным контейнером контейнера JPA договор.
LocalEntityManagerFactoryBean - по ссылке: FactoryBean, которая создает JPA EntityManagerFactory в соответствии со стандартным стандартом JPA автономной договор.
По существу, единственное различие заключается в том, как они создают JPA EntityManagerFactory
.
Ответ 3
LocalEntityManagerFactoryBean
является самым простым и самым ограниченным. Вы не можете ссылаться на существующий JDBC Определение DataSource bean и отсутствие поддержки глобальных транзакций.
LocalContainerEntityManagerFactoryBean
- самая мощная установка JPA , что позволяет использовать гибкую локальную конфигурацию в приложении. Он поддерживает ссылки на существующий JDBC DataSource, поддерживает как локальные, так и глобальные транзакции.
REF: spring -framework-reference.pdf "Spring 3"
Ответ 4
LocalEntityManagerFactoryBean создает управляемую приложениями EntityManagerFactory.
LocalContainerEntityManagerFactoryBean создает управляемый контейнером EntityManagerFactory.
Ссылка: Spring В действии - стены Крейга
Ответ 5
Спецификация JPA определяет два виды менеджеров объектов:
-
Менеджеры, управляемые приложением. Менеджеры событий создаются, когда приложение напрямую запрашивает один из диспетчера объектов factory. С объектом, управляемым приложениями менеджеров, приложение отвечает за открытие или закрытие менеджеров объектов и вовлечение менеджера организации в транзакции. Этот тип менеджера объектов наиболее подходящий для использования в автономных приложениях, которые не запускаются в Java EE контейнер.
-
Управляемые контейнером -Entity-менеджеры создаются и управляются Java EE контейнер. Приложение не взаимодействует с менеджером сущностей factory в все. Вместо этого менеджеры сущностей получают непосредственно через инъекции или из JNDI. Контейнер отвечает за настройку заводов-менеджеров объектов. Этот тип диспетчера объектов наиболее подходит для использования контейнером Java EE , который хочет сохранить некоторый контроль над конфигурацией JPA за пределами того, что указано в файле persistence.xml.
Управляемые приложения EntityManagers
создаются с помощью EntityManagerFactory
, полученного путем вызова метода createEntityManagerFactory()
для PersistenceProvider. Тем временем управляемые контейнером EntityManagerFactorys получаются с помощью метода PersistenceProviders createContainerEntityManagerfactory()
.
Каждый аромат менеджера объектов factory создается с помощью соответствующего Spring factory bean:
-
LocalEntityManagerFactoryBean
создает управляемую приложениями Entity- ManagerFactory. -
LocalContainerEntityManagerFactoryBean
создает управляемый контейнером EntityManagerFactory
Важно отметить, что выбор между управлением приложениями
EntityManagerFactory
и управляемый контейнером EntityManagerFactory
полностью прозрачен для приложения на основе Spring. Когда вы работаете с Spring и JPA, скрытые детали работы с любой формой EntityManagerFactory
скрыты, оставляя ваш код доступа к данным сфокусированным на его истинную цель: доступ к данным.
Единственное реальное различие между управляемыми приложениями и управляемыми контейнером фабриками управления объектами, что касается Spring, заключается в том, как каждый из них настроен в Spring контекст приложения.
Ответ 6
LocalEntityManagerFactoryBean создает EntityManagerFactory через PersistenceProvider.createEntityManagerFactory()
LocalContainerEntityManagerFactoryBean создает EntityManagerFactory через PersistenceProvider.createContainterEntityManagerFactory()
Ответ 7
- Обе реализации 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>
Обе реализации могут быть использованы в транзакциях, управляемых контейнером, пожалуйста, исправьте меня, если необходимо внести некоторые исправления.