2017-02-06 79 views
2

我最近創建了一個Web服務,它使用Java中的靜態方法獲取數據庫中的項目列表。EntityManagerFactory已關閉,休眠

該Web服務完美工作,並返回給調用者的JSON。但是,它只能使用一次。如果您嘗試刷新或發出新請求,我會收到EntityManagerFactory is closed錯誤。

這裏的Web服務類的樣子:

public class WebService extends HttpServlet { 

    @Override 
    protected void doGet(HttpServletRequest req, HttpServletResponse resp) 
      throws ServletException, IOException { 
    //obtain the list of vehicles from the database 
     List<Vehicle> vehicles = ExecuteVehicle.getVehicleList(); 

     //create the Gson object and generate the Json 
    Gson gson = new Gson(); 
     JsonElement element = gson.toJsonTree(vehicles, new TypeToken<List<Vehicle>>(){}.getType()); 

     //send the list of vehicles 
     JsonArray jsonArray = element.getAsJsonArray(); 
     resp.setContentType("application/json"); 
     resp.getWriter().print(jsonArray); 
    } 
} 

正如你所看到的,車輛的名單使用ExecuteVehicle.getVehicleList()方法進行填充。

下面是方法的樣子:

public static List<Vehicle> getVehicleList(){ 

     //open a Session 
     Session session = HibernateUtilities.getSessionFactory().openSession(); 

     //start a transaction 
     session.beginTransaction(); 

     //SELECT STATEMENT for the entire list of Vehicles 
     Query<Vehicle> query = session.getNamedQuery("SelectAllVehicles"); //query name is declared in the mapping file 
     List<Vehicle> vehicles = query.list(); 

     //commit the changes and end the transaction 
     session.getTransaction().commit(); 

     //close the Session 
     session.close(); 

     //close the SessionFactory 
     HibernateUtilities.getSessionFactory().close(); 

     return vehicles; 

    } 

這裏的HibernateUtilities類,需要照顧的會議等等:

public class HibernateUtilities { 
    private static SessionFactory sessionFactory; 
    private static StandardServiceRegistry standardServiceRegistry; 

    static{ 
     try { 
      //configure and build the service registry 
      standardServiceRegistry = new StandardServiceRegistryBuilder().configure("hibernate.cfg.xml").build(); 

      //create the metadata 
      Metadata metadata = new MetadataSources(standardServiceRegistry).getMetadataBuilder().build(); 

      //build the SessionFactory 
      sessionFactory = metadata.getSessionFactoryBuilder().build(); 
     } catch (HibernateException e) { 
      //in case the SessionFactory cannot be built, then the stackTrace is displayed 
      e.printStackTrace();   
     } 
    } 

    //method that returns the Hibernate session factory 
    public static SessionFactory getSessionFactory(){ 
     return sessionFactory; 
    } 
} 

我的問題是 - 我怎麼能避免EntityManagerFactory is closed錯誤。此外,我必須一次又一次地以實時的方式獲得這份清單。 Hibernate可行嗎?要實時獲取數據庫中的項目列表(例如,每2秒左右)?我知道這取決於項目的數量等等,但我從技術角度提出要求 - 根據我的理解,打開和關閉會話需要很長時間 - 我是否可以在同一會話中一遍又一遍地重複如果是這樣,怎麼樣?

謝謝!

回答

3

我會說你在那裏做得太多。

您必須刷新/提交交易並關閉會話,因爲您使用的是工廠的openSession()方法。

但我不認爲你需要關閉的SessionFactory本身

//close the SessionFactory 
HibernateUtilities.getSessionFactory().close(); 

刪除此行,你可以將能夠使用工廠多次。

+0

看來你是絕對正確的。有趣的是,我過去嘗試過這種方式,但它不起作用。我還可能刪除(註釋掉)'session.close();'代碼行。 我幾乎是一個完整的Hibernate初學者,並且不知道所有這些事情到底是什麼,我唯一能做的就是「猜測」或在教程中搜索他們到底做了什麼。 無論如何,它似乎現在工作!非常感謝! –

+0

順便說一下,是否有任何「危險」讓SessionFactory保持打開狀態?我應該以任何方式擔心嗎? –

+1

在我使用過的所有應用程序中,SessionFActory在啓動時創建了一次,並且僅在應用程序已關閉時才被銷燬。創建Factory是一個非常激烈的過程,一旦它創建,我就會離開它單獨。您必須關閉會話,因爲它們是有狀態的,但工廠是無狀態的,因此無需重新創建每個請求。 –