no data on all but first subreport

Hi, I have a report with some groups and the detail band has a subreport which is printed each time group changes, always with the same datasource..

my problem is that I get no data for all but first printed subreport and I think it happens because the datasource is emptied when it's used.

here is the report:

please someone take some time to help me, I really need a little push..

thanks,
Pedro.

Post edited by: radix, at: 2007/01/10 12:19

Post edited by: radix, at: 2007/01/10 12:20
Post edited by: radix, at: 2007/01/10 14:13

radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago

9 Answers:

Not exactly sure how to help you. As you correctly assumed, filling a subreport exhausts the data source passed to it.

Bearing this in mind, you can either
  • provide a fresh data source each time the subreport gets filled, i.e. don't reuse the data source across subreport instantiations

  • if your subreport is rewindable (i.e. it implements JRRewindableDataSource), make sure that you rewind the data source before/after you use it once. You can do this, for instance, in one of the scriptlet's methods (like beforeDetailEval()).

  • combine the two previous approaches by writing a rewindable data source wrapper that rewinds a data source and delegates all the calls to it:
    Code:
    <br />
    public class RewindableDSWrapper implements JRRewindableDataSource {<br />
      private final JRRewindableDataSource ds;<br />
      public RewindableDSWrapper(JRRewindableDataSource ds) {<br />
        this.ds = ds;<br />
        this.ds.moveFirst();<br />
      }<br />
      public boolean next() throws JRException {<br />
        return ds.next();<br />
      }<br />
      public Object getFieldValue(JRField jrField) throws JRException {<br />
        return ds.getFieldValue(jrField);<br />
      }<br />
      public void moveFirst() throws JRException {<br />
        ds.moveFirst();<br />
      }<br />
    }<br />
    -----<br />
    <subreport><br />
      <dataSourceExpression>new RewindableDSWrapper(..subreport ds..)</dataSourceExpression><br />
    </subreport><br />
    </td></tr></tbody></table></li>[/ul]<br />
    <br />
    HTH,<br />
    Lucian<br>Post edited by: lucianc, at: 2007/01/10 12:38
lucianc's picture
77046
Joined: Jul 17 2006 - 1:10am
Last seen: 1 hour 4 min ago
Lucian I just had another idea which I'm trying right now and consist in passing the datasource through a field to subreport..

It should be quick to try, I'll post some feedback.

If it fails I'll try your sugestion altough I found it a bit harder to do and since I'm a novice programmer it will take some more time to understand.

thanks,
Pedro.

ps: I also had to deface the screenshot cause my boss asked me to as this is an outsourcing project and our client shouldn't find that :)
radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago
Lucian my idea didn't work, I'm already trying to implement your sugestion, but I don't know where to define the Wrapper

thanks for your help,
pedro
radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago
Hi, I defined the RewindableDSWrapper class as you sugested, compiled it and put it into report directory.


Code:
import net.sf.jasperreports.engine.*;<br />
<br />
public class RewindableDSWrapper implements JRRewindableDataSource<br />
{<br />
	  public final JRRewindableDataSource ds;<br />
<br />
	  public RewindableDSWrapper(JRRewindableDataSource dsource)<br />
	  {<br />
	     this.ds = dsource;<br />
	     try {<br />
	            this.ds.moveFirst();<br />
	         }catch(Exception e) {}<br />
	       <br />
	  }<br />
<br />
	  public boolean next() throws JRException<br />
	  {<br />
	    return ds.next();<br />
	  }<br />
<br />
	  public Object getFieldValue(JRField jrField) throws JRException<br />
	  {<br />
	    return ds.getFieldValue(jrField);<br />
	  }<br />
<br />
	  public void moveFirst() throws JRException<br />
	  {<br />
	    ds.moveFirst();<br />
	  }<br />
	}</td></tr></tbody></table><br />
<br />
<br />
as you can see I added the try-catch so I could compile it.<br />
<br />
<br />
Then configured my main report to use that scriptlet class and configured the datasource expression of the sub report to:<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>new RewindableDSWrapper($P{ds_detalhe_movimentos})</td></tr></tbody></table><br />
<br />
When I try to compile the report it gives these errors:<br />
<br />
<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>Errors compiling .\report_pages.jasper.<br />
 net.sf.jasperreports.engine.JRException: Errors were encountered when compiling report expressions class file:<br />
1. The constructor RewindableDSWrapper(Object) is undefined<br />
                 value = (net.sf.jasperreports.engine.JRDataSource)(new RewindableDSWrapper(((java.lang.Object)parameter_ds_detalhe_movimentos.getValue()))); </td></tr></tbody></table><br />
<br />
<br />
I don't know if it is because my default datasource is not a RewindableDataSource and it cannot cast it.<br />
<br />
someone gimme a little help..<br />
<br />
thanks,<br />
pedro<br />
<br />
Post edited by: radix, at: 2007/01/10 19:06<br>Post edited by: radix, at: 2007/01/10 19:07
radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago
First of all, is your subreport data source a JRRewindableDataSource or not? You should know this before trying this solution.

The error is caused by the fact that you've declared the ds_detalhe_movimentos parameter as java.lang.Object. For the report to compile, you'll have to either declare it as net.sf.jasperreports.engine.JRRewindableDataSource (or a class/interface that extends it), or cast the parameter value yourself in the data source expression:
Code:
<br />
<dataSourceExpression>new RewindableDSWrapper((JRRewindableDataSource) $P{ds_detalhe_movimentos})</dataSourceExpression><br />
</td></tr></tbody></table><br />
<br />
HTH,<br />
Lucian
lucianc's picture
77046
Joined: Jul 17 2006 - 1:10am
Last seen: 1 hour 4 min ago
It wasn't a Rewindable Datasource, but it is now.
All my datasources Extend this Template class

Code:
public abstract class Template implements JRRewindableDataSource{	<br />
	<br />
	/* VARIAVEIS PRIVADAS */<br />
	/**<br />
	 * Current index of the result set<br />
	 */<br />
	protected int index = -1;<br />
.<br />
.<br />
.<br />
	public boolean next() throws JRException{<br />
		index++;<br />
		return (index < hashmap.size());<br />
	}<br />
	<br />
	public void moveFirst() throws JRException{<br />
		index = -1;<br />
	}</td></tr></tbody></table><br />
<br />
I declared the Parameter 'ds_detalhe_movimentos' as <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>net.sf.jasperreports.engine.JRRewindableDataSource</td></tr></tbody></table> set it to 'Use as a prompt' and set the datasource expression to <table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>new RewindableDSWrapper((JRRewindableDataSource) $P{ds_detalhe_movimentos})</td></tr></tbody></table><br />
<br />
the report has now compiled but I get this Error when I run the app on eclipse:<br />
<br />
<br />
this parts of the error should tell you what is happening (complete error on the end)<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>Error loading scriptlet class : RewindableDSWrapper<br />
	at net.sf.jasperreports.engine.fill.JRFillSubreport.prepare(JRFillSubreport.java:582)</td></tr></tbody></table><br />
<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>Caused by: java.lang.ClassNotFoundException: RewindableDSWrapper<br />
	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)</td></tr></tbody></table><br />
<br />
<br />
complete error:<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>Exception in thread "main" net.sf.jasperreports.engine.JRRuntimeException: net.sf.jasperreports.engine.JRException: Error loading scriptlet class : RewindableDSWrapper<br />
	at net.sf.jasperreports.engine.fill.JRFillSubreport.prepare(JRFillSubreport.java:582)<br />
	at net.sf.jasperreports.engine.fill.JRFillElementContainer.prepareElements(JRFillElementContainer.java:343)<br />
	at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:311)<br />
	at net.sf.jasperreports.engine.fill.JRFillBand.fill(JRFillBand.java:275)<br />
	at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillTitle(JRVerticalFiller.java:292)<br />
	at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:201)<br />
	at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:109)<br />
	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:751)<br />
	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:679)<br />
	at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:89)<br />
	at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:601)<br />
	at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:517)<br />
	at net.sf.jasperreports.engine.JasperRunManager.runReportToPdfFile(JasperRunManager.java:349)<br />
	at controller.CntrFormatter.initFormatter(CntrFormatter.java:228)<br />
	at initiation.Main.main(Main.java:24)<br />
Caused by: net.sf.jasperreports.engine.JRException: Error loading scriptlet class : RewindableDSWrapper<br />
	at net.sf.jasperreports.engine.fill.JRFillDataset.createScriptlet(JRFillDataset.java:452)<br />
	at net.sf.jasperreports.engine.fill.JRFillDataset.setParameterValues(JRFillDataset.java:592)<br />
	at net.sf.jasperreports.engine.fill.JRBaseFiller.setParameters(JRBaseFiller.java:864)<br />
	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:702)<br />
	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:679)<br />
	at net.sf.jasperreports.engine.fill.JRFillSubreport.fillSubreport(JRFillSubreport.java:499)<br />
	at net.sf.jasperreports.engine.fill.JRSubreportRunnable.run(JRSubreportRunnable.java:63)<br />
	at net.sf.jasperreports.engine.fill.JRThreadSubreportRunner.run(JRThreadSubreportRunner.java:137)<br />
	at java.lang.Thread.run(Thread.java:595)<br />
Caused by: java.lang.ClassNotFoundException: RewindableDSWrapper<br />
	at java.net.URLClassLoader$1.run(URLClassLoader.java:200)<br />
	at java.security.AccessController.doPrivileged(Native Method)<br />
	at java.net.URLClassLoader.findClass(URLClassLoader.java:188)<br />
	at java.lang.ClassLoader.loadClass(ClassLoader.java:306)<br />
	at sun.misc.Launcher$AppClassLoader.loadClass(Launcher.java:268)<br />
	at java.lang.ClassLoader.loadClass(ClassLoader.java:251)<br />
	at java.lang.ClassLoader.loadClassInternal(ClassLoader.java:319)<br />
	at java.lang.Class.forName0(Native Method)<br />
	at java.lang.Class.forName(Class.java:242)<br />
	at net.sf.jasperreports.engine.util.JRClassLoader.loadClassForName(JRClassLoader.java:90)<br />
	at net.sf.jasperreports.engine.fill.JRFillDataset.createScriptlet(JRFillDataset.java:447)<br />
	... 8 more</td></tr></tbody></table><br />
<br />
<br />
thanks for your patience.. your help is being precious..<br />
<br />
pedro.<br>Post edited by: radix, at: 2007/01/11 09:16
radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago
I've just tryied to define this:

Code:
public void beforeDetailEval() throws JRScriptletException<br />
{<br />
	(net.sf.jasperreports.engine.JRRewindableDataSource)getParameterValue("ds_detalhe_movimentos"«»).moveFirst()<br />
}<br />
/** end EVENT_BEFORE_DETAIL_EVAL Please don't touch or move this comment*/</td></tr></tbody></table><br />
<br />
on internal scriplet editor ant set report to use internal support and changed the data source expression to just<br />
<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>$P{ds_detalhe_movimentos}</td></tr></tbody></table><br />
<br />
but I get this error when compiling the report:<br />
<br />
<br />
<table align="center" border="0" cellpadding="3" cellspacing="1" width="90%"><tbody><tr><td><b>Code:</b></td></tr><tr><td><pre>Compiling scriptlet source file... C:\Documents and Settings\Pedro_M_D_Catalao\Desktop\novos_layouts_grupos\report_pagesScriptlet.java<br />
Error compiling the Scriptlet Java source.<br />
net.sf.jasperreports.engine.JRException:ÂErrorÂcompilingÂreportÂjavaÂsourceÂfilesÂ:ÂC:\DocumentsÂandÂSettings\Pedro_M_D_Catalao\Desktop\novos_layouts_grupos\report_pagesScriptlet.java ÂÂÂÂatÂnet.sf.jasperreports.engine.design.JRJdk13Compiler.compileClasses(JRJdk13Compiler.java:119) ÂÂÂÂatÂnet.sf.jasperreports.engine.design.JRAbstractMultiClassCompiler.compileClass(JRAbstractMultiClassCompiler.java:45) ÂÂÂÂatÂit.businesslogic.ireport.IReportCompiler.run(IReportCompiler.java:327) ÂÂÂÂatÂjava.lang.Thread.run(UnknownÂSource) CausedÂby:Âjava.lang.ClassNotFoundException:Âcom.sun.tools.javac.Main ÂÂÂÂatÂjava.net.URLClassLoader$1.run(UnknownÂSource) ÂÂÂÂatÂjava.security.AccessController.doPrivileged(NativeÂMethod) ÂÂÂÂatÂjava.net.URLClassLoader.findClass(UnknownÂSource) ÂÂÂÂatÂjava.lang.ClassLoader.loadClass(UnknownÂSource) ÂÂÂÂatÂsun.misc.Launcher$AppClassLoader.loadClass(UnknownÂSource) ÂÂÂÂatÂjava.lang.ClassLoader.loadClass(UnknownÂSource) ÂÂÂÂatÂjava.lang.ClassLoader.loadClassInternal(UnknownÂSource) ÂÂÂÂatÂjava.lang.Class.forName0(NativeÂMethod) ÂÂÂÂatÂjava.lang.Class.forName(UnknownÂSource) ÂÂÂÂatÂnet.sf.jasperreports.engine.util.JRClassLoader.loadClassForName(JRClassLoader.java:90) ÂÂÂÂatÂnet.sf.jasperreports.engine.design.JRJdk13Compiler.compileClasses(JRJdk13Compiler.java:81) ÂÂÂÂ...Â3Âmore</td></tr></tbody></table><br />
<br />
it does not matter much how it's done.. the first way that works is the one for me :)<br />
<br />
thanks.
radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago
it gives me the same error if I don't define anything on scriptlet editor but the option to use internal scriptlet support is selected

hope it helps
radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago
I managed to work it out redefining the next() method for my reusable datasource like this:

Code:
	public boolean next() throws JRException{<br />
		index++;<br />
		boolean teste = (index < hashmap.size());<br />
		if(!teste)index = -1;<br />
		return teste;<br />
	}</td></tr></tbody></table><br />
<br />
it works :)<br />
<br />
btw, in this case do I need to declare my Datasources as Rewindable ?<br />
<br />
thanks for the help,<br />
pedro
radix's picture
190
Joined: Nov 22 2006 - 5:45pm
Last seen: 16 years 6 months ago
Feedback
randomness