2015-04-06 2 views
0

J'ai une application JSP, Servlet (Pure JSP, Servlet) où il utilise Hibernate. Voici une classe d'implémentation Hibernate pour une table unique.Hibernate problème avec `SessionFactory`

DesignationImpl.java

package dao; 

import model.sub.DesigAllBean; 
import java.util.List; 
import model.main.Designation; 
import org.hibernate.Query; 
import org.hibernate.SQLQuery; 
import org.hibernate.Session; 
import org.hibernate.SessionFactory; 
import org.hibernate.Transaction; 
import org.hibernate.boot.registry.StandardServiceRegistryBuilder; 
import org.hibernate.cfg.Configuration; 

/** 
* 
* @author Yohan 
*/ 
public class DesignationImpl implements DesignationInterface 
{ 


    @Override 
    public Session openCurrentSession() { 
      Session currentSession = getSessionFactory().openSession(); 
      return currentSession; 
    } 

    @Override 
    public Transaction openTransaction(Session session) { 
     Transaction beginTransaction = session.beginTransaction(); 
     return beginTransaction; 
    } 

    private static SessionFactory getSessionFactory() { 

     Configuration configuration = new Configuration().configure(); 
     StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() 
         .applySettings(configuration.getProperties()); 
     SessionFactory sessionFactory = configuration.buildSessionFactory(builder.build()); 
     return sessionFactory; 
    } 

    @Override 
    public void save(Designation d, Session session) 
    { 
     session.save(d); 
    } 

    @Override 
    public void update(Designation d, Session session) 
    { 
     session.update(d); 
    } 
} 

est inférieure à la classe de service qui appelle à la classe ci-dessus.

DesignationService .java

package service; 

import dao.Common; 
import model.sub.*; 
import dao.DesignationImpl; 
import dao.DesignationInterface; 
import java.util.ArrayList; 
import java.util.List; 
import model.main.Designation; 
import org.hibernate.Session; 
import org.hibernate.Transaction; 

/** 
* 
* @author Yohan 
*/ 
public class DesignationService 
{ 
    private DesignationInterface designationInterface; 

    public DesignationService() 
    { 
     designationInterface = new DesignationImpl(); 
    } 

    public Session getSession() 
    { 
     Session session = designationInterface.openCurrentSession(); 
     return session; 
    } 

    public Transaction getTransaction(Session session) 
    { 
     return designationInterface.openTransaction(session); 
    } 

    public String save(Designation d) 
    { 
     Session session = designationInterface.openCurrentSession(); 
     Transaction transaction = null; 
     String result=""; 

     try 
     { 
      transaction = designationInterface.openTransaction(session); 
      designationInterface.save(d,session); 
      transaction.commit(); 
      result = Common.SAVE_SUCCESS; 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 

      if(transaction!=null) 
      { 
       transaction.rollback(); 
      } 
      result = Common.SAVE_ROLLBACK; 
     } 
     finally 
     { 
      session.close(); 
     } 

     return result; 
    } 

    public String update(Designation d) 
    { 
     Session session = designationInterface.openCurrentSession(); 
     Transaction transaction = null; 
     String result=""; 

     try 
     { 
      transaction = designationInterface.openTransaction(session); 
      designationInterface.update(d,session); 
      transaction.commit(); 
      result = Common.SAVE_SUCCESS; 
     } 
     catch(Exception e) 
     { 
      e.printStackTrace(); 

      if(transaction!=null) 
      { 
       transaction.rollback(); 
      } 
      result = Common.SAVE_ROLLBACK; 
     } 
     finally 
     { 
      session.close(); 
     } 

     return result; 
    } 
} 

Et les servlets les appellent comme ci-dessous.

DesignationService desigSrvc=new DesignationService(); 

     Designation designation=desigSrvc.findByForiegnKey(idEmployee); 

     Employee empl=new Employee(); 
     empl.setIdEmployee(idEmployee); 

     if(designation.getDateCreated()==null) 
     { 
      designation.setDateCreated(Common.getCurrentDateSQL()); 
     } 

     designation.setEmployee(empl); 
     designation.setDesignation(txtDesignation); 
     designation.setLocation(location); 
     designation.setSalary(salary); 
     designation.setDatePromoted(datePromoted); 
     designation.setLastUpdated(Common.getCurrentDateSQL());  

     desigSrvc.save(designation); 

Comme vous pouvez le voir, il y a une mauvaise chose qui se passe là-bas, à savoir les servlets créent de nouveaux cas SessionFactory chaque fois qu'il executes.I ai Driver#Connect questions et je pense que cela pourrait être la raison de ce .

Je lis les messages stackoverflow et certains semblent suggérer l'utilisation d'un seul SessionFactory pour l'ensemble de l'application. Si c'est approprié, alors comment puis-je le faire? Peut-être faire une classe singleton comme ci-dessous et l'utiliser dans mes cours d'implémentation?

public class SessionFactoryBuilder 
{ 
    private static SessionFactoryBuilder instance; 
    private static SessionFactory sessionFactory; 

    private SessionFactoryBuilder() 
    { 
    } 

    private static void buildConfig() 
    { 
     Configuration configuration = new Configuration().configure(); 
      StandardServiceRegistryBuilder builder = new StandardServiceRegistryBuilder() 
          .applySettings(configuration.getProperties()); 
      sessionFactory = configuration.buildSessionFactory(builder.build()); 
    } 

    public static SessionFactoryBuilder getInstance() 
    { 
     if(instance == null) 
     { 
      instance = new SessionFactoryBuilder(); 
      buildConfig(); 
     } 
     return instance; 
    } 

    public SessionFactory getSessionFactory() 
    { 
     return sessionFactory; 
    } 
} 

Mais alors, qu'en est-il des threads? Les servlets sont multi-threadées n'est-ce pas?

+0

Où est votre DesignationInterface ?? – Pratik

+0

Salut, vous devez créer une classe de fournisseur sessionfactory singleton .. Je pense qu'il devrait résoudre votre problème .. –

Répondre

2

Comme j'ai commenté j'ai la classe HibernateUtil.java comme Singleton. Cette classe peut vous fournir SessionFactory en utilisant HibernateUtil.getSessionFactory() et vous devez supprimer le code lié de votre classe DesignationImpl

public class HibernateUtil { 

private static StandardServiceRegistry serviceRegistry; 
private static SessionFactory INSTANCE = null; 
public static SessionFactory getSessionFactory() { 
    if(INSTANCE=null){ 
      createSessionFactory(): 
     } 
     return sessionFactory; 
} 
private synchronized static void createSessionFactory(){ 
    if(INSTANCE!=null){return;} 
    Configuration configuration = new Configuration(); 
    configuration.configure(); 
    SeviceRegistry=newStandardServiceRegistryBuilder().applySettings(configuration.getProperties()).build(); 
    sessionFactory = configuration.buildSessionFactory(serviceRegistry); 
    } 
    } 
} 

Trouver le code ci-dessus, et s'il vous plaît suggérer/commentaire à confirmer l'exactitude de code.I penser filetage sera pris en charge de l'utilisation de cela .. J'ajouter une double vérification pour éviter la création de multiples sessionfactory ad une ressource lourde.

+0

J'ai également posté ma classe de singleton. L'affaire est le problème de threading. J'ai entendu que 'SessionFactory' est thread-safe de toute façon. –

+0

La classe DesignationImpl est ce qui parle de ..? Je ne pense pas que ce soit SingleTon .. Je pense que cela crée sessionfactory chaque fois que vous appelez getSessionFactory() .. Pourriez-vous s'il vous plaît m'aider ou me corriger .. –

+0

Je parle de la classe 'SessionFactoryBuilder'. Dans ma question, j'ai mentionné que je l'ai également créé, même si je ne l'utilise pas. –