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配置详解

hibernate.hbm2ddl.auto配置详解

hibernate.hbm2ddl.auto配置详解

hibernate.hbm2ddl.auto =创建(不创建表)

Hibernate、MySQL 视图和 hibernate.hbm2ddl.auto = 验证

hibernate.hbm2ddl.auto Hibernate 如何决定何时创建或更新 ddl?