2015-05-26 57 views
0

我正在開發連接到PostgreSQL數據庫的Jersey應用程序。我正在尋找一種解決方案,如何配置Hibernate,使其始終正確連接到本地數據庫或基於Heroku的數據庫(取決於我在本地部署應用程序還是將其推送到Heroku)。使用本地和Heroku postgres數據庫的推薦Hibernate配置

使用Heroku導遊,我想是這樣的:

HibernateUtil.java:

private static SessionFactory buildSessionFactory() { 
    try { 
     // Create the SessionFactory from hibernate.cfg.xml 
     Configuration configuration = new Configuration(); 
     configuration.configure("hibernate.cfg.xml"); 

     configuration.setProperty("hibernate.connection.url", 
       System.getenv("DATABASE_URL")); 

     URI dbUri = new URI(System.getenv("DATABASE_URL")); 

     String username = dbUri.getUserInfo().split(":")[0]; 
     String password = dbUri.getUserInfo().split(":")[1]; 
     String dbUrl = "jdbc:postgresql://" + dbUri.getHost() + ':' 
       + dbUri.getPort() + dbUri.getPath(); 
     configuration 
       .setProperty("hibernate.connection.username", username); 
     configuration 
       .setProperty("hibernate.connection.password", password); 
     configuration.setProperty("hibernate.connection.url", dbUrl); 
     System.out.println("Hibernate Annotation Configuration loaded"); 

     ServiceRegistry serviceRegistry = new StandardServiceRegistryBuilder() 
       .applySettings(configuration.getProperties()).build(); 
     System.out.println("Hibernate Annotation serviceRegistry created"); 

     SessionFactory sessionFactory = configuration 
       .buildSessionFactory(serviceRegistry); 

     return sessionFactory; 
    } catch (Throwable ex) { 
     // Make sure you log the exception, as it might be swallowed 
     System.err.println("Initial SessionFactory creation failed." + ex); 
     throw new ExceptionInInitializerError(ex); 
    } 
} 

我的hibernate.cfg.xml是這樣的:

<?xml version="1.0" encoding="UTF-8"?> 
<!DOCTYPE hibernate-configuration PUBLIC 
     "-//Hibernate/Hibernate Configuration DTD 4.0//EN" 
     "http://hibernate.org/dtd/hibernate-configuration-3.0.dtd"> 
<hibernate-configuration> 
    <session-factory> 
     <!-- Database connection properties - Driver, URL, user, password --> 
     <property name="hibernate.dialect">org.hibernate.dialect.PostgreSQLDialect</property> 
     <property name="hibernate.connection.driver_class">org.postgresql.Driver</property> 
     <property name="hibernate.connection.url">jdbc:postgresql://localhost/MYAPP</property> 
     <property name="hibernate.connection.username">user</property> 
     <property name="hibernate.connection.password">password</property> 

     <!-- org.hibernate.HibernateException: No CurrentSessionContext configured! --> 
     <property name="hibernate.current_session_context_class">thread</property> 

     <!-- Mapping with model class containing annotations --> 
     <mapping class="com.example.object" /> 
    </session-factory> 
</hibernate-configuration> 

的想法是HibernateUtil覆蓋了hibernate.cfg.xml屬性(url,user,password)。部署在當地工作,但部署到Heroku的失敗:

遠程:[錯誤]未能執行目標de.juplo:hibernate4 - Maven的插件: .1.0:出口(默認)項目的myapp:目標去的執行默認。 juplo:hib rnate4-maven-plugin:1.1.0:導出失敗:錯誤調用驅動程序#連接:連接 n到localhost:5432被拒絕。檢查主機名和端口是否正確,並且postmaster正在接受TCP/IP連接。連接被拒絕 - > [幫助 ]

回答

0

它看起來像在Heroku上,你的應用程序使用從hibernate.cfg.xml而不是buildSessionFactory()方法的配置。你能確認buildSessionFactory()被叫嗎?

我想你應該從hibernate.cfg.xml中刪除hibernate.connection.*屬性,並在本地使用DATABASE_URL。你可以在你的env中設置它,或者把它放在一個.env文件中,然後在foreman start的本地運行你的應用程序,它會選擇這個文件。這是確保dev和prod環境之間配對的最佳方式,它將測試您的buildSessionFactory()代碼。

如果您想要following this guide,您甚至可以在本地使用Heroku數據庫。捕獲Heroku DATABASE_URL並將其放入您的.env文件中。然後將ssl=true&sslfactory=org.postgresql.ssl.NonValidatingFactory參數添加到JDBC URL。

+0

它看起來像第一次調用資源方法時調用buildSessionFactory()(調用當前SessionFactory來獲取當前Session的方法)。我認爲這個方法會在推送到heroku時被立即調用,然後它會根據Heroku的DATABASE_URL覆蓋屬性。我已經在本地設置了DATABASE_URL並且工作正常。在推向heroku時有沒有辦法調用buildSessionFactory()? – Daniel

+0

好的,我設法在Heroku上部署我的應用程序時使用類似於這個配置:http://stackoverflow.com/questions/12045070/how-do-i-configure-hibernate-orm-on-heroku。但現在的問題是,推送到heroku時不會自動創建表格,但我不知道爲什麼。我猜是因爲hibernate.cfg.xml中缺少hibernate.connection信息 – Daniel

+0

你有'hbm2ddl.auto'設置爲'update'嗎? – codefinger