web-dev-qa-db-fra.com

hibernate session.save () ne se reflète pas dans la base de données

Selon ma compréhension en veille prolongée (veuillez confirmer)

1- Vous devez session.close() si vous l'obtenez par getSessionFactory().openSession().
2- Pas besoin de session.close() si vous l'obtenez par getSessionFactory().getCurrentSession(). Il est automatiquement fermé après commit ().

3- @ 2 Lorsque vous utilisez getSessionFactory().getCurrentSession(), nous devons effectuer toutes les activités de base de données dans une transaction active afin de pouvoir valider () à la fin.

4- Hibernate met en file d'attente toutes les opérations de sauvegarde, de mise à jour et de suppression et les soumet au serveur de base de données uniquement après un flush () opération ou validation la transaction ou fermeture de la session dans lequel ces opérations ont lieu. (selon javadoc)

D'après les points ci-dessus, si je considère 1 & 4, le code suivant devrait fonctionner:

Session session = HibernateUtil.getSessionFactory().openSession();  
AccountDetails ac = new AccountDetails();  
//perform set operations  
session.save(ac);  
session.close();  
System.out.println("new account stored.");

MAIS cela ne fonctionne pas, c'est-à-dire qu'il fonctionne correctement mais ne reflète pas (stockage) dans la base de données. Pourquoi en est-il ainsi? Lorsque j'écris le code dans une transaction et que je le valide, il est stocké.

Je pense que je manque une chose de base. Précisez s'il vous plaît.

23
mukund

Lorsque vous créez une session à l'aide de SessionFactory.openSession (), aucune transaction n'est créée, vos opérations sont donc exécutées en dehors du contexte de transaction. Pour voir vos modifications, vous devez démarrer une nouvelle transaction ou effectuer vos opérations dans le cadre d'une transaction en cours. De la documentation:

Une transaction typique doit utiliser l'idiome suivant:

Session sess = factory.openSession();
 Transaction tx;
 try {
     tx = sess.beginTransaction();
     //do some work
     ...
     tx.commit();
 }
 catch (Exception e) {
     if (tx!=null) tx.rollback();
     throw e;
 }
 finally {
     sess.close();
 }
18
Dmitry Kuskov

J'essayais également de comprendre le point: save () peut effectuer une opération d'insertion en dehors des limites de la transaction alors j'ai fait quelque chose comme ça

SessionFactory factory = new Configuration().configure()
                    .buildSessionFactory();
            Session session = factory.openSession();

            session.save(user);

            session.close();

Mais les données ne sont pas insérées dans la base de données, j'ai donc essayé à nouveau et maintenant cela a fonctionné pour moi et les données ont été insérées avec succès:

dans le fichier de configuration:

  <property name="connection.autocommit">true</property>

et en Java code:

    SessionFactory factory = new Configuration().configure()
            .buildSessionFactory();
    Session session = factory.openSession();

    session.save(user);

    session.flush();
    session.close();
6
Vibhor Bhardwaj

Ouais session.save N'est pas enregistré dans la base de données sans avoir la transaction. La seule façon de le faire est d'utiliser le

<property name="connection.autocommit">true</property>

Si cette propriété est utilisée, vous n'avez pas besoin de transaction et vous n'avez pas besoin non plus de session.flush() ou session.close()

6
rsu

session.close () est uniquement responsable de fermer la session https://docs.jboss.org/hibernate/orm/3.5/javadocs/org/hibernate/Session.html#close ()

comment travailler avec une session de mise en veille prolongée: https://docs.jboss.org/hibernate/orm/3.3/reference/en/html/transactions.html#transactions-basics

// Non-managed environment idiom
Session sess = factory.openSession();
Transaction tx = null;
try {
    tx = sess.beginTransaction();

    // do some work
    ...

    tx.commit();
}

catch (RuntimeException e) {
    if (tx != null) tx.rollback();
    throw e; // or display error message
}
finally {
    sess.close();
}

Comme il l'a écrit dans la documentation: une solution beaucoup plus flexible est la gestion de contexte intégrée de la "session actuelle" d'Hibernate:

// Non-managed environment idiom with getCurrentSession()
try {
    factory.getCurrentSession().beginTransaction();

    // do some work
    ...

    factory.getCurrentSession().getTransaction().commit();
}
catch (RuntimeException e) {
    factory.getCurrentSession().getTransaction().rollback();
    throw e; // or display error message
}
3
Constantine Ch

Chaque fois que vous effectuez une unité de travail sur les objets de la base de données, les transactions doivent être utilisées. http://docs.jboss.org/hibernate/orm/4.0/hem/en-US/html/transactions.html montre pourquoi ils sont utilisés et comment ils peuvent être utilisés. Mais, la clé est d'utiliser un objet transaction en appelant session.beginTransaction() qui retourne un objet Transaction. Cela représentera l'unité de travail effectuée dans la base de données.

1
blackpanther

J'ai trouvé que je devais rincer puis rafraîchir le DAO, puis cela a fonctionné.

session.flush()
session.refresh(entityDAO)
1
Demian

Vous avez oublié de vous engager. Vous devriez vous engager.

session.save(ac);
// you should to add this bottom line  
session.getTransaction().commit();
0
Oguzhan Cevik