Может ли кто-нибудь объяснить, в чем разница между LocalContainerEntityManagerFactoryBean Spring Framework и LocalEntityManagerFactoryBean?
В чем разница между LocalContainerEntityManagerFactoryBean и LocalEntityManagerFactoryBean?
Ответы (8)
По сути, спецификация JPA определяет два типа менеджеров сущностей. Это:
i) Управляемый приложением: Диспетчер сущностей, управляемый приложением, означает, что «Менеджеры сущностей создаются и управляются только приложением (т. Е. Нашим кодом)».
ii) Контейнер, управляемый: Контейнер Управляемый диспетчер сущностей означает, что «диспетчеры сущностей создаются и управляются только контейнером J2EE (т. е. наш код не управляет напрямую, вместо этого диспетчеры сущностей создаются и управляются контейнером, а наши код получает EM каким-то образом, как при использовании JNDI).
Примечание. Создано и управляется (см. Выше) означает «открытие, закрытие и вовлечение менеджера объекта в транзакции».
LocalContainerEntityManagerFactoryBean - управляемый контейнером
LocalEntityManagerFactoryBean - управляемый приложением
Большое примечание: для приложений на основе Spring разница невелика. Spring играет только роли (как контейнер, если вы настроили LocalContainerEntityManagerFactoryBean, и как приложение, если вы настроили LocalEntityManagerFactoryBean < / em>)
В документации сказано все:
LocalContainerEntityManagerFactoryBeanager По ссылке: FactoryBean, который создает JPA EntityManagerFactory в соответствии со стандартным контрактом начальной загрузки контейнера JPA.
LocalEntityManagerFactoryBean - По ссылке: FactoryBean, который создает JPA EntityManagerFactory в соответствии со стандартным контрактом автономной начальной загрузки JPA.
По сути, разница только в том, как они создают JPA EntityManagerFactory
.
LocalEntityManagerFactoryBean
самый простой и самый ограниченный. Вы не можете ссылаться на существующее определение bean-компонента JDBC DataSource, и не существует поддержки глобальных транзакций.
LocalContainerEntityManagerFactoryBean
- это самый мощный вариант настройки JPA, позволяющий гибко настраивать локальную конфигурацию в приложении. Он поддерживает ссылки на существующий источник данных JDBC, поддерживает как локальные, так и глобальные транзакции.
ССЫЛКА: spring-framework-reference.pdf «Весна 3»
LocalEntityManagerFactoryBean создает объект EntityManagerFactory, управляемый приложением.
LocalContainerEntityManagerFactoryBean создает объект EntityManagerFactory, управляемый контейнером.
Ссылка: Весна в действии - Крейг Уоллс
Спецификация 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.
- Обе реализации 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>
Обе реализации могут использоваться в рамках транзакции, управляемой контейнером, пожалуйста, поправьте меня, если потребуется какое-то исправление.
Чтобы использовать JPA в проекте Spring, нам нужно настроить EntityManager.
Это основная часть конфигурации, и мы можем сделать это с помощью фабричного компонента Spring. Это может быть более простой LocalEntityManagerFactoryBean или более гибкий LocalContainerEntityManagerFactoryBean.
baeldung.com/the-persistence-layer-with-spring-and-jpa
LocalEntityManagerFactoryBean создает EntityManagerFactory через PersistenceProvider.createEntityManagerFactory ()
LocalContainerEntityManagerFactoryBean создает EntityManagerFactory через PersistenceProvider.createContainterEntityManagerFactory ()