web-dev-qa-db-fra.com

Quelle est la différence entre LocalContainerEntityManagerFactoryBean et LocalEntityManagerFactoryBean?

Quelqu'un peut-il expliquer quelle est la différence entre LocalContainerEntityManagerFactoryBean et LocalEntityManagerFactoryBean ?

35
BlueSky

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 )

30
Prashanth

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.

16

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"

16
Bassem Reda Zohdy

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

10
Chandana

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. 

5
PAA

LocalEntityManagerFactoryBean crée EntityManagerFactory via PersistenceProvider.createEntityManagerFactory ()

LocalContainerEntityManagerFactoryBean crée EntityManagerFactory via PersistenceProvider.createContainterEntityManagerFactory ()

0
Evgeniy Dorofeev
  • Les deux implémentations LocalEntityManagerFactoryBean et LocalContainerEntityManagerFactoryBean retournent une référence EntityManagerFactory À partir de Org.
  • Chaque implémentation utilisera la transaction resource_local à moins que nous Demandions explicitement à Spring d’utiliser JTA.
  • Une différence majeure entre les deux implémentations est LocalContainerEntityManagerFactoryBean fournir par programme Réglage unité de persistance (source de données et packageToScan), est plus flexible en ce que nous pouvons remplacer l'emplacement de la persistance. Le fichier xml est comparable à LocalEntityManagerFactoryBean dans lequel nous devons utiliser un nom prédéfini persistence.xml

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.

0
Jain