2013-02-13 14 views
6

Tôi đang sử dụng Hibernate kết hợp với Spring. Là cơ sở dữ liệu tôi hiện đang sử dụng HSQL, lưu trữ dữ liệu của nó trong một tệp (như SQLite). Đường dẫn đến tệp HSQL hiện được mã hóa cứng trong persistence.xml. Làm thế nào tôi có thể truy cập và thay đổi giá trị này khi chạy, vì vậy người dùng có thể tải và lưu từ/vào một tệp HSQL tùy ý?Thay đổi hibernate.connection.url từ bên trong Spring

persistence.xml:

<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
      xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
      xsi:schemaLocation="http://java.sun.com/xml/ns/persistence 
           http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
      version="1.0"> 

    <persistence-unit name="something-unit"> 
     <provider>org.hibernate.ejb.HibernatePersistence</provider> 

     <properties> 
      <property name="hibernate.connection.driver_class" value="org.hsqldb.jdbcDriver" /> 
      <property name="hibernate.connection.url" value="jdbc:hsqldb:file:~/something-db/somethingdb" /> 
      <property name="hibernate.connection.username" value="sa" /> 
      <property name="hibernate.dialect" value="org.hibernate.dialect.HSQLDialect" /> 
      <property name="hibernate.hbm2ddl.auto" value="update" /> 
     </properties> 
    </persistence-unit> 

</persistence> 

Xuân applicationContext.xml

<?xml version="1.0" encoding="UTF-8"?> 

<beans xmlns="http://www.springframework.org/schema/beans" 
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
     xmlns:context="http://www.springframework.org/schema/context" 
     xmlns:data="http://www.springframework.org/schema/data/jpa" 
     xmlns:tx="http://www.springframework.org/schema/tx" 
     xsi:schemaLocation=" 
       http://www.springframework.org/schema/beans 
       http://www.springframework.org/schema/beans/spring-beans.xsd 
       http://www.springframework.org/schema/context 
       http://www.springframework.org/schema/context/spring-context-2.5.xsd 
       http://www.springframework.org/schema/data/jpa 
       http://www.springframework.org/schema/data/jpa/spring-jpa.xsd 
       http://www.springframework.org/schema/tx 
       http://www.springframework.org/schema/tx/spring-tx-3.0.xsd"> 


    <!-- Database Setup --> 

    <bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalEntityManagerFactoryBean"> 
     <property name="persistenceUnitName" value="something-unit" /> 
    </bean> 

    <data:repositories base-package="com.something.playlist"/> 

    <!-- Transaction Setup --> 

    <tx:annotation-driven/> 

    <bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager"> 
     <property name="entityManagerFactory" ref="entityManagerFactory"/> 
    </bean> 

</beans> 

Thanks cho bất kỳ gợi ý!

+0

thêm tiền thưởng khi tôi cần một ví dụ cụ thể/trợ giúp thêm về vấn đề này. –

Trả lời

3

Bạn có thể chỉ định nguồn dữ liệu JNDI và chuyển nó tới Hibernate. Hoặc bạn có thể xác định chiến lược Plugin của riêng bạn để đạt được các kết nối JDBC bằng cách thực hiện các giao diện org.hibernate.connection.ConnectionProvider

Để biết thêm gợi ý xem: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html

Sửa 2/16: Có một ví dụ về StackOverflow khi tạo ConnectionProvider tùy chỉnh: How can I set Datasource when I'm creating Hibernate SessionFactory?

Nếu bạn định thay đổi nguồn dữ liệu khi đang di chuyển, thay vì lúc khởi động, bạn sẽ phải khởi động lại nhà máy phiên Hibernate. Để làm điều đó một cách chính xác, bạn sẽ phải chắc chắn rằng không có giao dịch nào đang chạy trong nó tại thời điểm khởi động lại. Sau câu hỏi/câu trả lời sẽ giúp bạn với điều đó: Hibernate Sessionfactory restart | Spring

+0

bạn có thể muốn tham gia tiền thưởng? ;-) –

+0

Tôi đã thêm một vài tham chiếu. Hy vọng điều này sẽ giúp bạn hoặc ai đó sẽ viết giải pháp hoàn chỉnh cho tiền thưởng. Chúc may mắn! – Olaf

1

Chiến lược thường được sử dụng là xác định tất cả cấu hình thời gian chạy trong một hoặc nhiều tệp * .properties và sử dụng PropertyPlaceholderConfigurer của mùa xuân để tải giá trị và thay thế trình giữ chỗ trong applicationContext.xml, đọc thêm tại đây: Best ways to deal with properties values in XML file in Spring, Maven and Eclipses.

app.properties:

# Dadabase connection settings: 
hibernate.connection.driver_class=org.hsqldb.jdbcDriver 
hibernate.connection.url=jdbc:hsqldb:file:~/something-db/somethingdb 
hibernate.connection.username=sa 
hibernate.connection.password=changeit 
hibernate.dialect=org.hibernate.dialect.HSQLDialect 
hbm2ddl.auto=update 
... ... 

applicationContext-dataStore.xml:

<bean class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer"> 
    <property name="locations"> 
    <list> 
     <!-- Default location inside war file --> 
     <value>classpath:app.properties</value> 
     <!-- Environment specific location, a fixed path on deployment server --> 
     <value>file:///opt/my-app/conf/app.properties</value> 
    </list> 
    </property> 
    <property name="ignoreResourceNotFound" value="true"/> 
</bean> 

... ... 

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="${hibernate.connection.driver_class}" /> 
    <property name="url" value="${hibernate.connection.url}" /> 
    <property name="username" value="${hibernate.connection.username}" /> 
    <property name="password" value="${hibernate.connection.password}" /> 
</bean> 

Một vấn đề ở đây là PropertyPlaceholderConfigurer không phân tích persistence.xml, giải pháp là để di chuyển tất cả các cấu hình hibernate vào tệp applicationContext.xml của Spring, vì không cần thiết đặt chúng trong persistence.xml. đọc thêm tại đây: loading .properties in spring-context.xml and persistence.xml.

persistence.xml:

<?xml version="1.0" encoding="UTF-8"?> 
<persistence xmlns="http://java.sun.com/xml/ns/persistence" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
    xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_1_0.xsd" 
    version="1.0"> 
    <persistence-unit name="JPAService" transaction-type="RESOURCE_LOCAL"/> 
</persistence> 

applicationContext-datSource.xml:

<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource"> 
    <property name="driverClassName" value="${hibernate.connection.driver_class}"/> 
    <property name="url" value="${hibernate.connection.url}"/> 
    <property name="username" value="${hibernate.connection.username}"/> 
    <property name="password" value="${hibernate.connection.password}"/> 
</bean> 

... ... 

<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean"> 
    <property name="persistenceXmlLocation" value="classpath:./META-INF/persistence.xml"/> 
    <property name="persistenceUnitName" value="JPAService"/> 
    <property name="dataSource" ref="dataSource"/> 

    <property name="jpaVendorAdapter"> 
     <bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"> 
      <property name="databasePlatform" value="${hibernate.dialect}"/> 
      <property name="showSql" value="true" /> 
      <property name="generateDdl" value="true"/> 
     </bean> 
    </property> 
    <property name="jpaProperties"> 
    <!-- set extra properties here, e.g. for Hibernate: --> 
    <props> 
     <prop key="hibernate.hbm2ddl.auto">${hbm2ddl.auto}</prop> 
    </props> 
    </property> 
</bean> 

Lưu ý rằng các ứng dụng web cần phải được khởi động lại mỗi khi bạn thay đổi cấu hình trong/opt/my-app /conf/app.properties, để thay đổi có hiệu lực.

Hy vọng điều này sẽ hữu ích.

+0

yorkw, cảm ơn bạn đã trả lời chi tiết. Nhưng nếu tôi hiểu bạn đúng, tôi không thể thay đổi hibernate.connection.url trên bay bằng cách sử dụng giải pháp của bạn? Tôi thực sự cần phải thay đổi điều này một cách nhanh chóng để người dùng có thể sử dụng ví dụ: tập tin - mở và sau đó chọn một tập tin bao gồm cơ sở dữ liệu HSQL. Bạn có bất kỳ gợi ý về điều này? Cảm ơn :-) –

1

Nếu bạn muốn sử dụng ngủ đông qua JPA Abstraction, bạn có thể viết mã hoặc dịch vụ của mình để sử dụng javax.persistence.EntityManagerFactory.Autowire một trong số này và gọi createEntityManager (Map map); Bạn có thể cung cấp nguồn dữ liệu trong bản đồ. Bạn có thể quấn trình quản lý thực thể bằng cách thực hiện của riêng bạn để kéo tham số ra khỏi luồng địa phương để tạo nguồn dữ liệu.

EDIT: Đọc sai ngữ cảnh và thấy bạn đang sử dụng EntityManagerFactory. Trong trường hợp đó chỉ cần đọc phần cuối cùng, nơi bạn quấn Nhà máy với đại biểu tạo nguồn dữ liệu chính xác từ một luồng địa lý.

Các vấn đề liên quan