我正在使用Spring + JPA + Hibernate开发一个网站。在持久性配置(JPA + Hibernate)中,我将HibernateJpaVendorAdapter的generateDdl属性设置为true,实际上新实体正确地在数据库中创建新表。
一旦创建了表,如果我向实体添加一个属性,我期望HibernateJpaVendorAdapter改变表并添加列。这种情况并没有发生,这很奇怪,因为在Java AbstractJpaVendorAdapter的setGenerateDdl方法文档中有:“设置是否在初始化EntityManagerFactory后生成DDL,创建/ 更新所有相关表。”
JPA + Hibernate配置:
<bean id="dataSource" class="org.springframework.jdbc.datasource.DriverManagerDataSource">
<property name="driverClassName" value="${db.driverClassName}" />
<property name="url" value="${db.url}" />
<property name="username" value="${db.username}" />
<property name="password" value="${db.password}" />
</bean>
<bean id="jpaAdapter" class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter">
<property name="databasePlatform" value="org.hibernate.dialect.MySQL5Dialect" />
<property name="showSql" value="${db.showSql}" />
<property name="generateDdl" value="${db.generateDdl}" />
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter" ref="jpaAdapter" />
<property name="jpaProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.format_sql">true</prop>
</props>
</property>
<property name="dataSource" ref="dataSource" />
</bean>
的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="m8tsPU" />
</persistence>
我做错了吗?
答案 0 :(得分:16)
通过直接设置适当的特定于Hibernate的属性,您可以对DDL生成进行更精细的控制:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
<property name="jpaProperties">
<props>
<prop key="hibernate.hbm2ddl.auto">update</prop>
...
</props>
</property>
</bean>
或者,您可以使用create-drop
代替update
,因为在某些情况下update
可能会导致问题。但请注意,自动DDL更新不适用于生产用途。
答案 1 :(得分:6)
或者,您也可以使用jpaPropertyMap
表达相同的属性:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
...
<property name="jpaPropertyMap">
<map>
<entry key="hibernate.hbm2ddl.auto" value="update"/>
...
</map>
</property>
</bean>
答案 2 :(得分:0)
也许到了晚了,但今天我在为遗留应用程序编写测试时遇到了同样的问题。
问题不仅发生在使用generateDdl
属性时,而且还会使用HSQL
。
要解决此问题,我将数据库从HSQL
更改为H2
,将数据源从org.springframework.jdbc.datasource.DriverManagerDataSource
更改为org.apache.commons.dbcp.BasicDataSource
。
spring-context.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: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/tx
http://www.springframework.org/schema/tx/spring-tx.xsd">
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource" destroy-method="close">
<property name="driverClassName" value="org.h2.Driver"/>
<property name="url" value="jdbc:h2:mem:test"/>
<property name="username" value="sa"/>
<property name="password" value=""/>
</bean>
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaVendorAdapter">
<bean class="org.springframework.orm.jpa.vendor.HibernateJpaVendorAdapter"/>
</property>
<property name="dataSource" ref="dataSource"/>
</bean>
<bean id="transactionManager" class="org.springframework.orm.jpa.JpaTransactionManager">
<property name="dataSource" ref="dataSource"/>
<property name="entityManagerFactory" ref="entityManagerFactory"/>
</bean>
<tx:annotation-driven/>
...
</beans>
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="TestPU" transaction-type="RESOURCE_LOCAL">
<properties>
<property name="hibernate.show_sql" value="true"/>
<property name="hibernate.format_sql" value="true"/>
<property name="hibernate.hbm2ddl.auto" value="create-drop"/>
<property name="hibernate.dialect" value="org.hibernate.dialect.H2Dialect"/>
</properties>
</persistence-unit>
</persistence>
我希望它有所帮助。