2015-05-26 33 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