我想使用带有grails jasper插件的子报表,我按照此URL(http://www.grails.org/plugin/jasper)的说明进行操作。这是我的代码:
域名簿
class Book {
static belongsTo = Library
Library library
String title
String author
String publisher
String category
static constraints={
title()
author()
publisher()
category()
}
}
域名库:
class Library {
static hasMany = [ books : Book ]
String name
String adresse
Date dateMaturity
static constraints = {
}
String toString()
{
return name
}
}
在我的BookController中,我有:
def createReport = {
def books = Book.list()
chain(controller:'jasper',action:'index',model:[data:books],params:params)
}
在我的LibraryController中,我有:
def createReport = {
def library = Library.list()
chain(controller:'jasper',action:'index',model:[data:library],params:params)
}
我的jasper部分是:
我有一个SubReport文件:books.jasper(获取图书清单) 还有一个MasterReport:library.jasper(获取库列表)。
在我的MasterReport(库)中,我添加了子报表,我希望每个库都显示它包含的书籍列表;这是我的图书馆代码:
<parameter name="SUBREPORT_DIR" class="java.lang.String" isForPrompting="false">
...
<field name="books" class="java.util.Collection"/>
...
<subreport isUsingCache="true">
<reportElement x="0" y="25" width="437" height="100"/>
<dataSourceExpression><![CDATA[new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{books})]]></dataSourceExpression>
<subreportExpression class="java.lang.String"><![CDATA[$P{SUBREPORT_DIR} + "books.jasper"]]>
</subreportExpression>
</subreport>
我有这个错误:
错误500:在插件[jasper]中执行控制器[JasperController]的操作[index]导致异常:net.sf.jasperreports.engine.fill.JRExpressionEvalException:评估表达式时出错:源文本: new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($ F {books})
异常消息:无法懒惰地初始化角色集合:bookshelf.Library.books,没有关闭会话或会话
感谢您的帮助。
答案 0 :(得分:1)
Jasper报告只是期望对象列表。它不了解GORM查询。所以我们的方法是创建一个单独的对象列表,我们将其命名为“View Objects”,然后将它们发送给jasper报告而不是域类。
class LibraryVO {
List books
String name
String adresse
Date dateMaturity
}
class bookVO {
String title
String author
String publisher
String category
}
您可以将列表初始化为
List data=[]
LibraryVo libVo= new LibraryVO(...) // inalise it here
libVo.books = [new BookVO(),new BookVO()]
data << libVO
将列表传递给jasper控制器
(chain(controller:'jasper',action:'index',model:[data:data],params:params).
答案 1 :(得分:0)
我发现了这个问题:
在我的图书馆域名中,我只是添加了一个带有“books lazy:false”的映射:
class Library {
static hasMany = [ books : Book ]
String name
String adresse
Date dateMaturity
static constraints = {
}
static mapping = {
books lazy: false
}
String toString()
{
return name
}
}
现在,我的报告没有问题!
grails jasper插件使用链将模型从一个动作链接到下一个动作(chain(controller:'jasper',action:'index',model:[data:library],params:params
)。
之后,在jasper控制器中我们通过这一行获得模型:
def testModel = this.getProperties().containsKey('chainModel')?chainModel:null
出于某种原因,在图书馆馆藏中,我们在图书清单上有错误,例如:org.hibernate.LazyInitializationException:懒得初始化集合 - 没有会话或会话被关闭
通过使用“lazy:false”,我们将拉出域类的所有其他实例。
还有其他方法可以解决这个问题吗?
答案 2 :(得分:0)
LazyInitializationException是因为testModel中的对象未附加到当前的hibernate会话。我刚刚通过黑客攻击JasperController来解决这个问题:
class JasperController {
JasperService jasperService
// We need this to access the current hibernate session
def sessionFactory
def index = {
println(params)
def testModel = this.getProperties().containsKey('chainModel') ? chainModel : null
// Re-attach model objects to avoid LazyInitializationException.
def session = sessionFactory.getCurrentSession()
testModel?.data?.each
{
session.update(it)
}
JasperReportDef report = jasperService.buildReportDefinition(params, request.getLocale(), testModel)
generateResponse(report)
}
......等等。这会重新附加模型对象,避免LIE(不必急于获取)
答案 3 :(得分:0)
我有一个* .jasper(DataSource XML。我用过iReport)。如何传递它(以XML格式书)??
事先谢谢
答案 4 :(得分:0)
您可以使用jasper报告来调用您的gorm,但您需要将报告的语言设置为 groovy 而不是java,因为它是默认值。然后,如果使用子报表,则需要禁用jasper报表多线程并添加其他jar。它只是完美的工作。