Grails 和 Oracle Anydata

Posted

技术标签:

【中文标题】Grails 和 Oracle Anydata【英文标题】:Grails and Oracle Anydata 【发布时间】:2013-10-17 17:48:54 【问题描述】:

我正在尝试为 Oracle 表创建一个简单的 Groovy & Grails 接口,该表(在其他几列中)包含 1 列数据类型为 ANYDATA。 (我是 G&G 的新手,请多多包涵。)

虽然域类很容易让我将列映射到 sqltype“sys.anydata”,但控制器似乎无法处理这个问题。我得到典型的错误: ORA-00932: 不一致的数据类型: 预期的 CHAR 得到了 CHAR

由于处理 Oracle anydata 列可能很棘手,这并不让我感到惊讶,并且可能需要大量 grails 辅助工作才能使其正常工作。

首先,我猜我需要重写控制器的保存方法,以便将字符串转换为 ANYDATA 以便成功插入。甚至不知道从哪里开始...通常在 oracle SQL 中,您会使用类似的东西:

插入 mytable (id, anydatacol) 值 (1, sys.anyData.convertVarchar2('mystring'))

在您的 INSERT SQL 中获取插入任何数据的字符串。

如何自定义一个控制器以像上面那样插入(使用字段上的某些功能)而不是罐头保存方法?

我很想看到 grails 和 anydata 的工作示例,但无论我在 grails 中使用 anydata 能走多远,我都对如何自定义上述控制器感到好奇。



非常感谢,这似乎很有帮助!

取得一些进展。一切都可以编译,但是当我运行应用程序时,我得到:

Running Grails application
| Error 2013-10-17 22:33:29,123 [startStop-1] ERROR hbm2ddl.SchemaUpdate  - could not complete schema update
Message: No Dialect mapping for JDBC type: 2002
    Line | Method
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    724 | run       in java.lang.Thread
| Server running. Browse to

我的数据库是 Oracle 11g,我正在使用方言 org.hibernate.dialect.Oracle10gDialect...也尝试过 11 并且会引发相同的错误。

我需要做一些其他配置来使用自定义用户类型吗?从您发布的链接中,我创建了一个课程。除此之外,我的班级看起来像:

class Anytest 

    String name
    AnyScalarData anytdat

    static mapping = 
        table 'ANYTDAT'
        anytdat type:AnyScalarData, sqltype: "sys.anydata"

    


    static constraints = 
        name(blank:false)
        anytdat(nullable:true)
    

编辑:

更新了 Config.groovy:

grails.gorm.default.mapping = 'user-type'( type:AnyScalarDataUserType, class:AnyScalarData )

但现在得到:

Running Grails application
| Error 2013-10-17 23:01:27,441 [localhost-startStop-1] ERROR context.GrailsContextLoader  - Error initializing the application: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.codehaus.groovy.grails.exceptions.GrailsDomainException: Error evaluating ORM mappings block for domain [anydata_01.Anytest]:  No such property: AnyScalarDataUserType for class: org.codehaus.groovy.grails.orm.hibernate.cfg.HibernateMappingBuilder
Message: Error creating bean with name 'transactionManagerPostProcessor': Initialization of bean failed; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.codehaus.groovy.grails.exceptions.GrailsDomainException: Error evaluating ORM mappings block for domain [anydata_01.Anytest]:  No such property: AnyScalarDataUserType for class: org.codehaus.groovy.grails.orm.hibernate.cfg.HibernateMappingBuilder
    Line | Method
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 
|   1145 | runWorker in java.util.concurrent.ThreadPoolExecutor
|    615 | run . . . in java.util.concurrent.ThreadPoolExecutor$Worker
^    724 | run       in java.lang.Thread
Caused by BeanCreationException: Error creating bean with name 'transactionManager': Cannot resolve reference to bean 'sessionFactory' while setting bean property 'sessionFactory'; nested exception is org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory': Invocation of init method failed; nested exception is org.codehaus.groovy.grails.exceptions.GrailsDomainException: Error evaluating ORM mappings block for domain [anydata_01.Anytest]:  No such property: AnyScalarDataUserType for class: org.codehaus.groovy.grails.orm.hibernate.cfg.HibernateMappingBuilder
->>  262 | run       in java.util.concurrent.FutureTask
- - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - 

【问题讨论】:

对此还有什么想法吗? 【参考方案1】:

使用 DomainClass:创建自定义 UserType

Grails 在后台使用 Hibernate。我搜索了但没有找到Oracle的ANYDATA的映射类型,所以你需要实现一个custom User Type。基本上它将转换为 Hibernate 如何从数据库中检索和检索您的列。

Here's a example,我发现它具有适用于 ANYDATA 的 UserType。

使用 sql

由于您是 Grails 的新手,值得一提的是,您也可以直接使用 SQL,而无需使用域类。服务示例:

class MyService 
  def dataSource

  void addNewRecord(String data) 
    groovy.sql.Sql sql = new Sql(dataSource)
    sql.execute("insert into my_table(my_anydata_clomn) values(sys.anyData.convertVarchar2(?))",[data])
  


【讨论】:

以上是关于Grails 和 Oracle Anydata的主要内容,如果未能解决你的问题,请参考以下文章

使用 GRAILS、GROOVY、ORACLE 和 API KEY 保护 REST API

在 Grails 和 SpringSecurity 中访问 Oracle Internet Directory (OID) 中的嵌套 LDAP 角色

将Oracle数据库连接到Grails 3

grails数据库配置的问题

Grails 没有从 BuildConfig.groovy 将 jars 添加到类路径

如何获取 Grails 的 jasper 报告的数据源连接?