Quelqu'un peut-il expliquer quelle est la différence entre LocalContainerEntityManagerFactoryBean et LocalEntityManagerFactoryBean ?
Fondamentalement spécification JPA définit deux types de gestionnaires d’entités . Elles sont :
i) Géré par l'application: Gestionnaire d'entité gérée par application signifie "Les gestionnaires d'entité sont créés et gérés par la seule application (c'est-à-dire notre code)".
ii) Gestion des conteneurs: Gestionnaire d'entités géré par un conteneur signifie "Les gestionnaires d'entités sont créés et gérés par le conteneur J2EE uniquement (en d'autres termes, notre code ne gère pas directement. Les gestionnaires d'entités sont créés et gérés par conteneur, et nos codes reçoivent les EM. par un moyen comme utiliser JNDI).
Remarque: Créé et géré (ci-dessus) signifie "ouverture, fermeture et implication du responsable de l'entité dans les transactions".
LocalContainerEntityManagerFactoryBean - conteneur géré
LocalEntityManagerFactoryBean - application gérée
Remarque importante: Pour les applications basées sur les ressorts, la différence n'est pas très grande . Spring joue uniquement des rôles (en tant que conteneur si vous configurez LocalContainerEntityManagerFactoryBean et en tant que application si vous configurez LocalEntityManagerFactoryBean )
La documentation dit tout:
LocalContainerEntityManagerFactoryBean - À partir du lien: FactoryBean qui crée une entité JPA EntityManagerFactory conformément au contrat standard conteneur bootstrap de JPA.
LocalEntityManagerFactoryBean - À partir du lien: FactoryBean qui crée une entité JPA EntityManagerFactory conformément au contrat standard standalone bootstrap de JPA.
La seule différence réside essentiellement dans la manière dont ils créent la JPA EntityManagerFactory
.
LocalEntityManagerFactoryBean
est le plus simple et le plus limité. Vous ne pouvez pas faire référence à une définition de bean JDBC DataSource existante et aucune prise en charge des transactions globales n’existe.
LocalContainerEntityManagerFactoryBean
est la plus puissante des options de configuration JPA , permettant une configuration locale flexible au sein de l'application. Il prend en charge les liens vers un JDBC DataSource existant, prend en charge les transactions locales et globales.
REF: spring-framework-reference.pdf "Spring 3"
LocalEntityManagerFactoryBean génère une entité EntityManagerFactory gérée par l'application.
LocalContainerEntityManagerFactoryBean génère un EntityManagerFactory géré par le conteneur.
Réf: Spring In Action - Craig Walls
La spécification JPA définit deux Types de gestionnaires d’entités:
Application-managed - Les gestionnaires d'entités sont créés lorsqu'une application en demande directement À une fabrique de gestionnaires d'entités. Avec les gestionnaires D'entités gérées par l'application, l'application est responsable de l'ouverture ou de la fermeture des gestionnaires d'entité Et de l'implication du responsable de l'entité dans les transactions. Ce type de gestionnaire d’entités est le plus approprié pour une utilisation dans des applications autonomes qui ne s’exécutent pas dans un conteneur Java EE .
Géré par conteneur - Les gestionnaires d'entités sont créés et gérés par un conteneur Java EE . L’application n’interagit pas avec la fabrique de gestionnaires d’entités à . Au lieu de cela, les gestionnaires d’entités sont obtenus directement par injection ou par JNDI. Le conteneur est responsable de la configuration des fabriques du gestionnaire d'entités. Ce type de gestionnaire d'entités convient parfaitement à un conteneur Java EE Qui souhaite conserver un certain contrôle sur la configuration JPA au-delà de ce qui est spécifié dans la persistance. .xml.
Les applications gérées EntityManagers
sont créées par un EntityManagerFactory
obtenu en appelant la méthode createEntityManagerFactory()
de PersistenceProvider. Pendant ce temps, container-managed EntityManagerFactorys est obtenu via la méthode createContainerEntityManagerfactory()
de PersistenceProvider.
Chaque saveur d’entité manager est produite par un haricot Spring correspondant:
LocalEntityManagerFactoryBean
génère une entité gérée par l'application - ManagerFactory.
LocalContainerEntityManagerFactoryBean
produit une EntityManagerFactory gérée par conteneur
Il est important de souligner que le choix fait entre un EntityManagerFactory
géré par une application et un EntityManagerFactory
géré par un conteneur est totalement transparent pour une application Spring. Lorsque vous travaillez avec Spring et JPA, les détails complexes liés au traitement de l'une des deux formes de EntityManagerFactory
sont masqués, ce qui permet à votre code d'accès aux données de se concentrer sur son véritable objectif: l'accès aux données.
La seule différence réelle entre les fabriques gestionnaire de l'application et gérées par le conteneur / entité, en ce qui concerne Spring, est la manière dont chacune est configurée dans le contexte de l'application Spring.
LocalEntityManagerFactoryBean crée EntityManagerFactory via PersistenceProvider.createEntityManagerFactory ()
LocalContainerEntityManagerFactoryBean crée EntityManagerFactory via PersistenceProvider.createContainterEntityManagerFactory ()
Si les deux utilisent resource_local par défaut, la règle ne spécifie pas que LocalContainerEntityManagerFactoryBean utilise une transaction gérée par conteneur et l'autre utilise une transaction gérée par une application.
Lors de l'utilisation de JPA en dehors d'un conteneur d'injection de dépendance, les développeurs doivent gérer les transactions par programme. Si vous utilisez JPA à l'intérieur du conteneur d'injection de dépendance Spring, vous pouvez le gérer par le conteneur Spring.
Exemple d'utilisation de 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();
}
}
Erreur avec LocalEntityManagerFactoryBean
Java.lang.IllegalStateException: non autorisé à créer une transaction sur EntityManager partagé - utilisez plutôt des transactions Spring ou un 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>
Code de travail avec LocalEntityManagerFactoryBean
Transaction gérée par le ressort, telle que gérée par le conteneur dans le cas de 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>
Les deux implémentations peuvent être utilisées dans le cadre d'une transaction gérée par conteneur. Veuillez me corriger si une correction est nécessaire.