hibernate.hbm2ddl.auto + Oracle 中的自定义 sql 类型
Posted
技术标签:
【中文标题】hibernate.hbm2ddl.auto + Oracle 中的自定义 sql 类型【英文标题】:hibernate.hbm2ddl.auto + custom sql-type in Oracle 【发布时间】:2013-08-22 08:23:36 【问题描述】:我正在尝试将 JUnit 测试功能添加到已经使用 Spring (2.5.6)、Hibernate (3.2.6) 和 Oracle 11g DBMS 的旧代码库中。我希望 Hibernate 在 HSQLDB 内存数据库中生成所有表。不幸的是,现有的 Hibernate 映射使用 Oracle DB 的用户定义数据类型,这阻止了使用 HSQLDB 而不是 Oracle DB。
这是我的 application-context-test.xml:
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE beans PUBLIC "-//SPRING//DTD BEAN//EN" "http://www.springframework.org/dtd/spring-beans.dtd">
<beans>
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:mydb" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
<bean id="sessionFactory"
class="org.springframework.orm.hibernate3.LocalSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.dialect">org.hibernate.dialect.HSQLDialect</prop>
<prop key="hibernate.current_session_context_class">thread</prop>
<prop key="hibernate.transaction.factory_class">org.hibernate.transaction.JDBCTransactionFactory</prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.show_sql">true</prop>
<prop key="hibernate.hbm2ddl.auto">create</prop>
</props>
</property>
<property name='mappingResources'>
<list>
<value>first.hbm.xml</value>
<value>second.hbm.xml</value>
</list>
</property>
</bean>
这对我的大多数业务对象都很有效。不幸的是,表生成器似乎无法处理我的某些业务对象使用的用户定义类型。这个 hbm.xml 文件在我删除 varchar2 的“sql-type”属性之前无法工作:
<?xml version="1.0"?>
<!DOCTYPE hibernate-mapping PUBLIC "-//Hibernate/Hibernate Mapping DTD 3.0//EN"
"http://hibernate.sourceforge.net/hibernate-mapping-3.0.dtd">
<hibernate-mapping>
<class name="first"
table="FIRST">
<!-- ... -->
<property name="someBoolean" type="yes_no">
<column name="SOME_BOOLEAN" length="1" sql-type="varchar2"></column>
<!-- ... -->
</class>
</hibernate-mapping>
此外,这些用户类型的默认值也不起作用:
<property name="someOtherBoolean" type="yes_no">
<column name="SOME_OTHER_BOOLEAN" length="1" not-null="true" default="no"/>
</property>
删除这些用户类型将导致应用程序继续工作,但架构验证(验证)失败并显示
Wrong column type ... Found: varchar2, expected: char1(1 char)
如何在保留用户定义类型的同时生成表?谢谢!
编辑:我尝试通过将“sql.syntax_ora=true”添加到我的 application-context-test.xml 来激活对 Oracle 语法的支持:
<bean id="dataSource" class="org.apache.commons.dbcp.BasicDataSource"
destroy-method="close">
<property name="driverClassName" value="org.hsqldb.jdbcDriver" />
<property name="url" value="jdbc:hsqldb:mem:mydb;sql.syntax_ora=true" />
<property name="username" value="sa" />
<property name="password" value="" />
</bean>
然而,一切都没有改变。此选项要么不支持用户定义的类型,要么我未能正确应用它。
编辑 2: 我只是使用了 HSQLDB (2.3.0) 的最新快照,而不是旧的 1.8.1.3。这改变了映射错误,但没有解决它们。例如,现在我有
unexpected token: NO
在以下映射处:
<property name="someOtherBoolean" type="yes_no">
<column name="SOME_OTHER_BOOLEAN" length="1" not-null="true" default="no"/>
</property>
总结:最新版本的 HSQLDB 也没有适当的 Oracle 支持。
编辑 3: 只是想更新到 Hibernate 4.1.1,因为使用的 3.2.6 可能太旧了。可悲的是,我现在无法解决不兼容的问题。如果升级能解决我的问题会很有趣 - 任何人都可以使用 4.x 版本的 Hibernate 生成具有给定 Oracle 属性的表吗?
【问题讨论】:
【参考方案1】:为了避免验证消息,columnDefinition = "varchar2(1)"
对我有帮助:
@Column(name="BOOLEAN_COLUMN", columnDefinition = "varchar2(1)")
@Type(type = "yes_no")
private Boolean booCol;
【讨论】:
感谢您的回答,事实证明这是正确的。重要的部分是参数“(1)”,我一开始就错过了。这使得 Oracle 和 HSQLDB 可以读取映射。以上是关于hibernate.hbm2ddl.auto + Oracle 中的自定义 sql 类型的主要内容,如果未能解决你的问题,请参考以下文章
hibernate.hbm2ddl.auto =创建(不创建表)