IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Hibernate Java Discussion :

bdd supprimée après création à chaque nouvel entitymanagerfactory créé


Sujet :

Hibernate Java

  1. #1
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2024
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2024
    Messages : 2
    Points : 3
    Points
    3
    Par défaut bdd supprimée après création à chaque nouvel entitymanagerfactory créé
    Bonjour à toutes et tous,

    Je débute en java.

    Je souhaite créer une base de données et la remplir au lancement d'une application. Cela fonctionne parfaitement. J'utilise les annotations de mappage et un fichier persistence.xml avec l'unité de persistance suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
     
        <persistence-unit name="unity">
            <properties>
                <property name="hibernate.dialect" value="org.hibernate.community.dialect.SQLiteDialect" />
                <property name="jakarta.persistence.jdbc.driver" value="org.sqlite.JDBC" />
                <!-- la bdd doit être recréé à chaque lancement du programme -->
                <property name="hibernate.hbm2ddl.auto" value="create"/>
                <!-- afficher le sql joué par Hibernate -->
                <property name="hibernate.show_sql" value="false"/>
                <!-- formater le sql (sans quoi il est affiché en ligne) -->
                <property name="hibernate.format_sql" value="true"/>
            </properties>
        </persistence-unit>
    J'ai utilisé la valeur "create" car je veux que la bdd soit créée à chaque lancement de l'application (c'est une nécessité). Les données de la base n'ont d'intérêt que durant l'exécution de l'application.

    Voici comment je crée mes managers d'entité :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
            EntityManagerFactory emf = Persistence.createEntityManagerFactory(AppConfiguration.PERSISTENCE_UNIT_NAME_INITIALIZATION, Collections.singletonMap("jakarta.persistence.jdbc.url",AppConfiguration.jdbcUrl));
     
    EntityManager em = emf.createEntityManager();
     
    //debut de la transaction
    //persistance de plusieurs objets
    //commit
     
    //fermeture des ressources des managers
      emf.close();
      em.close();
    A ce niveau, ma base de données a été créée et contient des lignes. Jusque là, pas de problème.

    Par contre, dès que je veux faire une insertion complémentaire, j'écris de nouveau le même code que précédemment :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
     
    EntityManagerFactory emf = Persistence.createEntityManagerFactory(AppConfiguration.PERSISTENCE_UNIT_NAME_INITIALIZATION, Collections.singletonMap("jakarta.persistence.jdbc.url",AppConfiguration.jdbcUrl));
     
    EntityManager em = emf.createEntityManager();
     
    //debut de la transaction
    //persistance d'un objet
    //commit
     
    //fermeture des ressources des managers
      emf.close();
      em.close();
    Et là, ma base de donnée ne contient que le dernier élément que j'ai inséré. Tout le reste à disparu.

    J'imagine que c'est par rappport à la valeur "create" utilisé dans la configuration de la propriété suivante :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
     <property name="hibernate.hbm2ddl.auto" value="create"/>
    La base de données est de nouveau créée (donc vidée) à chaque fois que je crée un nouvel EntityManagerFactory (en tout cas, c'est le constat que j'ai fait).

    Donc, comment dois-je m'y prendre pour que :

    - au lancement de l'application, ma base de données est créée et remplie (ce que j'arrive à faire mais peut être que je devrais faire autrement)
    - durant l'exécution de l'application, je dois pouvoir interroger la base de données, ajouter des éléments, en modifier, en supprimer, bref un usage classique de la bdd. Mais comment dois-je le faire. J'ai regardé beaucoup de tutos mais à chaque fois, je n'ai qu'un exemple qui ne mobilise q'une seule transaction.

    En plus de cela, je me pose donc quelques questions :
    * faut-il un entitymanagerfactory et un entitymanager pour chaque transaction ?

    Je me suis créé une classe pour récupérer plus facilement l'entitymanager mais est-ce que ce que je fais est correcte ?
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
     
    public class EntityManagerUtil {
     
        EntityManagerFactory emf;
        EntityManager em;
     
        public EntityManagerUtil() {
            this.emf = Persistence.createEntityManagerFactory(AppConfiguration.PERSISTENCE_UNIT_NAME_INITIALIZATION, Collections.singletonMap("jakarta.persistence.jdbc.url",AppConfiguration.jdbcUrl));
            this.em = emf.createEntityManager();
        }
     
        protected EntityManagerFactory getEntityManagerFactory(){
            return emf;
        }
     
        public EntityManager getEntityManager(){
            return em;
        }
     
        public void closeResourcesManager () {
            if (em != null && em.isOpen()) {
                em.close();
            }
            if (emf != null && emf.isOpen()) {
                emf.close();
            }
        }
     
    }
    Sincèrement, j'ai passé beaucoup de temps à chercher en ligne, en faisant pas mal d'essais mais après plusieurs heures, j'avoue ne pas trouver la solution.

    Merci de m'éclairer sur les questions posées et sur une solution ou une piste.

    Bien à vous.

  2. #2
    Modérateur

    Profil pro
    Inscrit en
    Septembre 2004
    Messages
    12 551
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2004
    Messages : 12 551
    Points : 21 607
    Points
    21 607
    Par défaut
    Hello,

    en principe il faut créer un seul EntityManager au début de ton programme, une seule fois, puis plus jamais une fois que le programme a démarré. Pour que les différentes parties de ton programme puissent utiliser la base de données avec cet EntityManager, il faut le leur donner d'une manière ou d'une autre.

    Dans la construction de tes objets ou en paramètre de tes méthodes. Ou alors avec un anti-patron à base de static comme une variable globale au programme entier.

    En fait en usage typique tout le monde est passé à l'injection de dépendance qui fait en sorte de lier les objets entre eux sans avoir besoin de le programmer, donc c'est facile d'avoir un singleton manager accessible directement partout où on en a besoin. Et surtout, ce qui utilise une base de données c'est surtout des serveurs web qui tournent avec Spring Boot ou équivalent qui configurent tout ça tout seul, et du coup plus personne n'a les difficultés que tu pourrais avoir.

    Et pour l'EntityManagerFactory, comme son nom le suggère, tu n'en as besoin que le temps de fabriquer l'EntityManager. Donc au début de ton programme, pour faire le manager et ensuite tu peux laisser la factory se perdre, plus jamais besoin.
    N'oubliez pas de consulter les FAQ Java et les cours et tutoriels Java

  3. #3
    Candidat au Club
    Homme Profil pro
    Enseignant
    Inscrit en
    Février 2024
    Messages
    2
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Aisne (Picardie)

    Informations professionnelles :
    Activité : Enseignant
    Secteur : Enseignement

    Informations forums :
    Inscription : Février 2024
    Messages : 2
    Points : 3
    Points
    3
    Par défaut
    Merci beaucoup Thelvin pour ta réponse.

    J'ai donc créé une classe selon le pattern singleton. Cette classe me retourne un entitymanager et laisse "se perdre" l'entitymanagerfactory :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
     
    public class MyEntityManager {
     
        private static EntityManagerFactory emf;
     
        private MyEntityManager() {
            emf = Persistence.createEntityManagerFactory(AppConfiguration.PERSISTENCE_UNIT_NAME, ConfigureEntityManagerFactory.getProperties());
        }
     
        public static EntityManager getNewEntityManager(){
     
            if( emf == null || !emf.isOpen()){
                emf = Persistence.createEntityManagerFactory(AppConfiguration.PERSISTENCE_UNIT_NAME, ConfigureEntityManagerFactory.getProperties());
            }
     
            return emf.createEntityManager();
     
        }
     
        public static void closeEntityManagerFactory() {
            emf.close();
        }
     
    }
    De fait, dois-je fermer mon entitymanagerfactory à la fermeture de mon application ?

    Pour l'entitymanager, j'ai lu (des choses qui se contredisent) qu'il faut en principe utiliser un entitymanager par transaction, que cela peut occuper pas mal de ressources de laisser un entitymanager constamment ouvert. Du coup, pour l'instant, j'appelle la méthode "close()" sur celui-ci mais est-ce vraiment pertinent. Après avoir lu tant de choses, je ne sais pas s'il vaut mieux utiliser la même instance d'entitymanager ou de la recréer. Mon application peut faire jusqu'à 200 accès par minutes à la base de données, cela signifie que je créé jusqu'à 200 entitymanagers. Je veux bien un point de vue éclairé sur le sujet.

    Je n'ai pas utilisé Sping Boot car je n'ai pas de serveur, c'est une base de données sqlite qui est construite à chaque démarrage de l'application et alimentée en fonction du contenu d'un répertoire cible. Aurais-je dû le faire ? J'ai une partie graphique avec javafx et une partie non graphique).

    Merci

Discussions similaires

  1. Réponses: 6
    Dernier message: 27/08/2006, 18h57
  2. Supprimer Gnome & installer un nouvel environnement
    Par vdumont dans le forum Gnome
    Réponses: 9
    Dernier message: 05/04/2006, 18h06
  3. MAJ d'un attibut pour chaque nouvelle entrée
    Par yoshï dans le forum PostgreSQL
    Réponses: 1
    Dernier message: 24/03/2006, 13h06
  4. Bases à supprimé après une installation de SQL Server ?
    Par webtheque dans le forum MS SQL Server
    Réponses: 2
    Dernier message: 29/03/2005, 16h57

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo