2013-02-13 10 views
6

Używam Hibernuj w połączeniu ze sprężyną. Jako baza danych używam obecnie HSQL, który przechowuje dane w pliku (np. SQLite). Ścieżka do pliku HSQL jest obecnie zakodowana w pliku persistence.xml. Jak uzyskać dostęp do tej wartości w czasie wykonywania i zmienić ją, aby użytkownik mógł załadować i zapisać z/do dowolnego pliku HSQL?Zmień plik hibernate.connection.url ze źródła

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> 

Wiosna 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> 

Dzięki za podpowiedź!

+0

dodał nagrodę, ponieważ potrzebuję konkretnego przykładu/więcej pomocy. –

Odpowiedz

3

Można określić źródło danych JNDI i przekazać je do trybu hibernacji. Można też zdefiniować własną strategię wtyczki do uzyskania połączenia JDBC poprzez implementację interfejsu org.hibernate.connection.ConnectionProvider

Aby uzyskać więcej wskazówek zobaczyć: http://docs.jboss.org/hibernate/orm/3.3/reference/en/html/session-configuration.html

Edit 2/16: Jest przykładem na StackOverflow na temat tworzenia niestandardowego ConnectionProvider: How can I set Datasource when I'm creating Hibernate SessionFactory? Jeśli zamierzasz zmienić źródło danych w locie, a nie przy starcie, będziesz musiał ponownie uruchomić fabrykę sesji Hibernate. Aby zrobić to poprawnie, musisz upewnić się, że żadne transakcje nie są w nim uruchomione w momencie ponownego uruchomienia. Poniższe pytania/odpowiedzi pomogłyby Ci w tym: Hibernate Sessionfactory restart | Spring

+0

może chcesz dołączyć do nagrody? ;-) –

+0

Dodałem kilka referencji. Mam nadzieję, że to pomoże wam albo komuś, kto napisze kompletne rozwiązanie dla nagrody. Powodzenia! – Olaf

1

Powszechnie stosowaną strategią jest definiowanie wszystkich konfiguracji środowiska wykonawczego w jednym lub kilku plikach * .properties i użycie właściwości PropertyPlaceholderConfigurer sprężyny w celu załadowania wartości i zastąpienia obiektu zastępczego w pliku applicationContext.xml, czytaj więcej tutaj: 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> 

Problemem tutaj jest PropertyPlaceholderConfigurer nie analizować persistence.xml, rozwiązaniem jest przeniesienie wszystkich konfiguracji hibernacji w aplikacji applicationContext.xml Spring, ponieważ nie ma potrzeby ustawiania ich w pliku persistence.xml. czytaj więcej tutaj: 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> 

Należy pamiętać, że aplikacja internetowa musi być ponownie uruchomiony za każdym razem, gdy zmienia konfigurację w/opt/My-app /conf/app.properties, aby wprowadzić zmiany.

Mam nadzieję, że to pomoże.

+0

yorkw, dziękuję za tę szczegółową odpowiedź. Ale jeśli rozumiem, że masz rację, nie mogę zmienić hibernate.connection.url w locie za pomocą twojego rozwiązania? Tak naprawdę muszę to zmienić w locie, aby użytkownik mógł użyć np. plik - otwórz, a następnie wybierz plik zawierający bazę danych HSQL. Czy masz jakieś wskazówki na ten temat? Dzięki :-) –

1

Jeśli chcesz użyć hibernacji za pośrednictwem WZP, możesz napisać swój kod lub usługę, aby użyć javax.persistence.EntityManagerFactory.Autowiruj jedną z nich i wywołaj createEntityManager (mapa mapy); Możesz podać źródło danych na mapie. Możesz zawinąć menedżer encji za pomocą własnej implementacji, która usuwa parametr z wątku lokalnego w celu utworzenia źródła danych.

EDYCJA: Niewłaściwie odczytano kontekst i zobaczyłem, że korzystasz z EntityManagerFactory. W takim przypadku po prostu przeczytaj ostatnią część, w której opakowujesz Factory za pomocą delegata, który tworzy poprawne źródło danych z wątkulokalnego.

Powiązane problemy