【问题标题】:Running Jasper Reports against an in-memory h2 datasource?针对内存中的 h2 数据源运行 Jasper 报告?
【发布时间】:2011-11-02 21:48:04
【问题描述】:

我正在尝试针对实时和报告数据库运行 jasper 报告,但是针对实时数据库运行的任何报告都会引发关于找不到正确表的异常(尽管找到了默认的 PUBLIC 架构)。看起来主 DataSource 连接不支持指定 IGNORECASE=true 的 H2 连接设置,因为生成的列和表是大写的,而我的查询不是。

DataSource.groovy 数据源:

dataSource {
    hibernate {
        cache.use_second_level_cache = false
        cache.use_query_cache = false
    }

    dbCreate = "create-drop" // one of 'create', 'create-drop','update'
    pooled = true
    driverClassName = "org.h2.Driver"
    username = "sa"
    password = ""
    url = "jdbc:h2:mem:testDb;MODE=PostgreSQL;IGNORECASE=TRUE;DATABASE_TO_UPPER=false"
    jndiName = null
    dialect = null 
}

Datasources.groovy 数据源:

datasource(name: 'reporting') {
    environments(['development', 'test'])
    domainClasses([SomeClass])
    readOnly(false)
    driverClassName('org.h2.Driver')
    url('jdbc:h2:mem:testReportingDb;MODE=PostgreSQL;IGNORECASE=TRUE;DATABASE_TO_UPPER=false')
    username('sa')
    password('')
    dbCreate('create-drop')
    logSql(false)
    dialect(null)
    pooled(true)
    hibernate {
        cache {
            use_second_level_cache(false)
            use_query_cache(false)
        }
    }
}

什么失败了:

JasperPrint print = JasperFillManager.fillReport(compiledReport, params,dataSource.getConnection())

在调试时,我发现的唯一区别是实时数据源在注入或使用DatasourcesUtils.getDataSource(null) 查找时是TransactionAwareDatasourceProxy,而DatasourcesUtils.getDataSource('reporting')BasicDataSource

Jasper 需要做什么才能对活动的内存 H2 数据库进行操作?

此故障无法在真实的 postgres 数据库中重现。

【问题讨论】:

    标签: postgresql grails jasper-reports grails-orm h2


    【解决方案1】:

    只是不要针对内存中的数据源运行报告,这不会成为问题。

    【讨论】:

      【解决方案2】:

      H2 目前不支持不区分大小写的标识符(表名、列名)。我知道其他数据库支持它,但目前 H2 使用常规的 java.util.HashMap<String, ..> 作为元数据,并且区分大小写(无论是否使用 IGNORECASE)。

      在这种情况下,标识符名称区分大小写。我尝试使用 H2 控制台使用数据库 URL jdbc:h2:mem:testReportingDb;MODE=PostgreSQL;IGNORECASE=TRUE;DATABASE_TO_UPPER=false

      DROP TABLE IF EXISTS UPPER;
      DROP TABLE IF EXISTS lower;
      CREATE TABLE UPPER(NAME VARCHAR(255));
      CREATE TABLE lower(name VARCHAR(255));
      
      -- ok:
      SELECT * FROM UPPER;
      SELECT * FROM lower;
      
      -- fail (table not found):
      SELECT * FROM upper;
      SELECT * FROM LOWER;
      

      所以,问题是:在创建表时,它们是使用大写标识符还是不同的数据库 URL 创建的?有可能改变吗?如果不是:是否可以使用不同的数据库 URL?

      【讨论】:

      • 问题是在这两种情况下表格都是由 GORM 自动创建的,所以我不明白为什么上限会随机变化。
      • 您可以通过将 ;TRACE_LEVEL_FILE=2 添加到数据库 URL 来验证执行了哪些语句 - 然后检查 .trace.db 文件。
      • +1 用于跟踪。如果我有时间,我明天会试试看。我现在的解决方法是不使用内存数据库运行报告,由一些智能布线控制
      【解决方案3】:

      您可能正在打开不同的数据库。使用数据库 URL jdbc:h2:mem:testDb 将打开一个 in-memory database within the same process and class loader

      您是否尝试过使用常规的持久性数据库,使用数据库 URL jdbc:h2:~/testDb

      要打开在不同进程或类加载器中运行的内存数据库,您需要使用server mode。这意味着,您需要在数据库运行的位置start a server,并使用jdbc:h2:tcp://localhost/mem:testDb 连接到它。

      另请参阅database URL overview

      【讨论】:

      • autoServer=TRUE 仍然失败,并且手动启动数据库不是一种选择。 jdbc:h2:~/testDb 失败,就像明确使用文件引用一样,锁定模式和关闭延迟的所有组合。第二个内存数据库工作,并且连接可以被正在运行的grails应用程序 jasper报告使用。
      • 你用的是什么版本的H2? “失败”是指表格不可用?如果遇到异常,可以发布吗?
      • 我更新了我的问题。问题似乎是表和列在 H2 中大写,考虑到IGNORECASE=true,这应该没问题,但是当我通过连接时,使用小写表/列名称的查询失败,只有一个数据源。我正在使用 H2 1.3.159。
      • 所以这显然不是正确的答案。我现在写了另一个答案。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-15
      • 1970-01-01
      相关资源
      最近更新 更多