【问题标题】:Grails throws Table "xxx" not foundGrails 抛出未找到表“xxx”
【发布时间】:2012-02-13 00:07:33
【问题描述】:

在 Grails 中,我可以在 BootStrap 中将域对象创建到内存数据源中的 H2 并返回正常的结果,但是一旦应用程序启动(例如来自 GSP 或控制器的查询)并且我尝试运行我得到一个查询:

org.h2.jdbc.JdbcSQLException: Table "FUNCTIONAL_DOC_TYPE" not found; SQL statement:
select this_.id as id1_0_, this_.version as version1_0_, this_.direction_id as direction3_1_0_, this_.functional_group_id as functional4_1_0_, this_.type_name as type5_1_0_ from functional_doc_type this_ [42102-147]
 at org.h2.message.DbException.getJdbcSQLException(DbException.java:327)
 at org.h2.message.DbException.get(DbException.java:167)
 at org.h2.message.DbException.get(DbException.java:144)
 at org.h2.command.Parser.readTableOrView(Parser.java:4562)
 at org.h2.command.Parser.readTableFilter(Parser.java:1020)
 at org.h2.command.Parser.parseSelectSimpleFromPart(Parser.java:1622)
 at org.h2.command.Parser.parseSelectSimple(Parser.java:1729)
 at org.h2.command.Parser.parseSelectSub(Parser.java:1616)
 at org.h2.command.Parser.parseSelectUnion(Parser.java:1461)
 at org.h2.command.Parser.parseSelect(Parser.java:1449)
 at org.h2.command.Parser.parsePrepared(Parser.java:401)
 at org.h2.command.Parser.parse(Parser.java:275)
 at org.h2.command.Parser.parse(Parser.java:247)
 at org.h2.command.Parser.prepare(Parser.java:201)
 at org.h2.command.Parser.prepareCommand(Parser.java:214)
 at org.h2.engine.Session.prepareLocal(Session.java:425)
 at org.h2.engine.Session.prepareCommand(Session.java:374)
 at org.h2.jdbc.JdbcConnection.prepareCommand(JdbcConnection.java:1056)
 at org.h2.jdbc.JdbcPreparedStatement.<init>(JdbcPreparedStatement.java:71)
 at org.h2.jdbc.JdbcConnection.prepareStatement(JdbcConnection.java:233)
 at org.apache.commons.dbcp.DelegatingConnection.prepareStatement(DelegatingConnection.java:281)
 at org.apache.commons.dbcp.PoolingDataSource$PoolGuardConnectionWrapper.prepareStatement(PoolingDataSource.java:313)
 at org.grails.datastore.gorm.GormStaticApi.findAll(GormStaticApi.groovy:374)
  • 我已经清理了构建

  • 运行 Grails 2.0.0

  • 我有多个到 SQL 服务器 DB 的数据源,它们只调用 StoredProcedures,现在找到了一个用例,在内存存储中使用 H2,使用良好的旧域对象...该错误仅发生在
    域。

  • 我运行了 dbconsole,发现的唯一表是标准 28
    “内部”表...没有来自我的应用程序

一些来源:

Datasource.groovy

// "Parent" datasource def

dataSource_messages {
    pooled = true
    driverClassName = "net.sourceforge.jtds.jdbc.Driver"
    username = "user"
    password = "secret"
    readOnly = "true"
}


// environment specific settings
environments {
    development {
        dataSource {
            dbCreate = "create-drop" // one of 'create', 'create-drop', 'update', 'validate', ''
            url = "jdbc:h2:mem:app_data;MVCC=TRUE"
            pooled = true
            driverClassName = "org.h2.Driver"
            username = "sa"
            password = ""
            readOnly = false
        }
        dataSource_messages {
            url = "jdbc:jtds:sqlserver://localhost:1433;DatabaseName=Messages"
        }

领域类:

class FunctionalDocType {
    String typeName
    FunctionalGroup functionalGroup
    DocDirection direction

    static constraints = {
        functionalGroup(nullable: true)
    }

}

Bootstrap.groovy:

   new FunctionalDocType(typeName: 'Order',   direction: buyerToSeller, functionalGroup: orders).save().save(flush: true)

   //  insert into functional_doc_type (id, version, direction_id, functional_group_id, type_name) values (null, ?, ?, ?, ?)


   FunctionalDocType.findAll() runs:

    // DEBUG SQL - select this_.id as id1_0_, this_.version as version1_0_, this_.direction_id as direction3_1_0_, this_.functional_group_id as functional4_1_0_, this_.type_name as     type5_1_0_ from functional_doc_type this_

并返回所有正确的值。

所以它就像在某个地方引导后删除了内存中的标签,但这没有被记录。

任何帮助表示赞赏。

谢谢,

史蒂夫

【问题讨论】:

  • 如果你使用持久化数据库(数据库 URL jdbc:h2:~/test/app_data;MVCC=TRUE),它可以工作吗?
  • +1 给你 Thomas,谢谢你的回答;这似乎确实有效。我仍然不确定为什么它不能以第一种方式工作,我还没有收到 Grails 小组的消息,但我认为持久数据存储应该适合我的用例。再次感谢您。

标签: hibernate grails h2


【解决方案1】:

H2 在最后一个连接关闭时关闭数据库。对于内存数据库,关闭连接意味着数据丢失...

因此,如果您始终保持一个连接打开,那么您应该没问题。您可以称其为“哨兵”连接。

另一种选择是使用持久数据库(数据库 URL jdbc:h2:~/test/app_data;MVCC=TRUE

【讨论】:

    【解决方案2】:

    大多数内存数据库将数据库与使用的连接联系起来。 Hibernate 为每个会话打开一个连接,因此只有带有 SchemaExport 的会话才具有具有正确模式的数据库并立即处理。要解决这个问题,您必须对访问内存数据库的所有会话使用相同的连接。

    connection = session.getConnection();
    
    sessionfactory.openSession(connection);
    

    【讨论】:

    • 感谢 Firo,吸取了教训。我已经假设因为 Grails 默认情况下用于开发模式是使用内存中的它是可以的,所以有一些信心这不会发生。所以我想如果我没有在 Bootstrap 上运行数据库操作,那么我就不会看到这个问题。无论如何,感谢您和 Thomas,我有 2 个不错的选择可以探索并了解更多关于内存数据库的信息。干杯!
    猜你喜欢
    • 2016-03-03
    • 2021-07-19
    • 1970-01-01
    • 2012-02-14
    • 2013-02-07
    • 2020-09-28
    • 1970-01-01
    • 2017-10-13
    • 2015-03-19
    相关资源
    最近更新 更多