2010-04-28 5 views
1

Я хотел был бы использовать subreports с плагинами янтаря grails, я последовали за руководством на этом url (http://www.grails.org/plugin/jasper). Вот мой код:Как использовать вложенные отчеты jasperreports с плагином ящеров grails?

домена Книга:

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) 
} 

Моя яшма часть:

У меня есть SubReport файл: books.jasper (получить список книг).
Также MasterReport: library.jasper (получить список библиотек).

В моем MasterReport (library), я добавил subreport, я хотел бы, для каждой библиотеки, показать список книг, которые он содержит; Вот мой код библиотеки:

<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: Выполнение действия [индекс] контроллера [JasperController] в плагине [яшма] вызывается исключение: net.sf. jasperreports.engine.fill.JRExpressionEvalException: Ошибка вычисления выражения: Исходный текст: новый net.sf.jasperreports.engine.data.JRBeanCollectionDataSource ($ F {} книги)
Сообщение исключения: не удалось инициализировать лениво коллекцию роли: bookshelf.Library.books, сеанс или сеанс не закрыты

Благодарим за помощь.

ответ

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 
    } 

Вы можете initializ списка как

List data=[] 

LibraryVo libVo= new LibraryVO(...) // inalise it here 
libVo.books = [new BookVO(),new BookVO()] 

data << libVO 

И передать список Джаспер контроллеру

(chain(controller:'jasper',action:'index',model:[data:data],params:params). 
+0

Используя «def library = Library.list()», у меня также есть список, и я передаю также свой список контроллеру яшмы. Какая разница? –

+0

Library.list() предоставляет вам список объектов домена, лениво извлеченных, так что книги еще не извлекаются из базы данных. Они будут получены по требованию. Но список LibraryVO, который мы передаем, уже будет иметь объекты книги. И поэтому нам не нужно говорить «ленивый»: ложный. Извлечение объектов лениво - это работа сеанса спящего режима, и отчеты яшмы полностью не знают об этом. –

0

Я считаю этот вопрос:

В моей библиотеке домена, я просто добавить отображение с «книгой ленивой: ложью»:

class Library { 

    static hasMany = [ books : Book ] 

    String name 
    String adresse 
    Date dateMaturity 

    static constraints = { 
    } 

    static mapping = { 
    books lazy: false 
    } 

     String toString() 
    { 
     return name 
    } 
} 

А теперь у меня есть мой отчет witout неприятности!


В Grails яшмы использовать плагин цепь для цепей модели от одного действия к следующему (chain(controller:'jasper',action:'index',model:[data:library],params:params).

После, в контроллере яшмы мы получаем модель по этой линии:

def testModel = this.getProperties().containsKey('chainModel')?chainModel:null 

По какой-то причине, в коллекции библиотеки, мы имеем ошибку на список книг, например: org.hibernate.LazyInitializationException: не удалось лениво инициализировать коллекцию - сеанс не был закрыт

Используя «lazy: false», мы вытягиваем все остальные экземпляры класса домена.

Есть ли другой способ исправить эту проблему?

0

LazyInitializationException происходит потому, что объекты в TestModel не привязаны к текущей сессии спящем , Я только что получил вокруг этого путем взлома 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 (без необходимости получать выборку)

0

У меня есть * .jasper (DataSource XML. Я использовал iReport). Как это можно передать (книга как XML)?

Спасибо заранее

+2

попробуйте опубликовать новый вопрос, если вы ищете помощь по проблеме кодирования. –

0

Вы можете использовать отчет яшмы для вызова GORM но вам нужно установить язык для доклада заводного не Java, как это по умолчанию. Затем, если вы используете подзаголовки, вам нужно отключить многопоточность отчета jasper и добавить дополнительные банки. Это просто отлично работает.

Смежные вопросы