Subreport with return value gives exception "System is not facet valid with enumeration" - jasper-reports

I'm getting an exception during compile in Jaspersoft Studio 6.4.0.
How do I address this?
I've created a report containing a subreport from which I want to return a value. To do that, I have:
Created a variable in the subreport called, "logTotal", set to the
value of another variable, which is a summation calculated in the
report. No reset type, no calculation function.
Created a variable in the main report with the same name and type.
No reset type, no calculation function.
In the main report, created a subreport return value link
between the two variables with calculation type, "System."
On compile, I'm seeing the following exception:
net.sf.jasperreports.engine.JRException: org.xml.sax.SAXParseException; lineNumber: 454; columnNumber: 91; cvc-enumeration-valid:
Value 'System' is not facet-valid with respect to enumeration '[Nothing, Count, DistinctCount, Sum, Average, Lowest, Highest, StandardDeviation, Variance, First]'. It must be a value from the enumeration.
I can choose the "System" choice from a
If I use other choices ("No calculation function," "First," "Average," etc.),
the subreport returns null.
Main Report:
<variable name="logTotal" class="java.math.BigDecimal" resetType="None"/>
...
<subreport>
<reportElement positionType="Float" x="0" y="60" width="572" height="40" uuid="d3ec84fb-528f-41f5-8b54-26112fd95b50"/>
<subreportParameter name="loadList">
<subreportParameterExpression><![CDATA[$P{loadList}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<returnValue subreportVariable="logTotal" toVariable="logTotal" calculation="System"/>
<subreportExpression><![CDATA["scaling/reports/ScaleSummary_Logs.jasper"]]></subreportExpression>
</subreport>
Subreport:
<variable name="price4" class="java.math.BigDecimal" calculation="Sum">
<variableExpression><![CDATA[$F{price}]]></variableExpression>
</variable>
<variable name="logTotal" class="java.math.BigDecimal" resetType="None">
<variableExpression><![CDATA[$V{price4}]]></variableExpression>
</variable>

It seems that the exception is the result of a mismatch between what JS Studio permits and what this particular compiler (not sure whether JSS uses the compiler I installed (6.4.1) or one that it installs) allows.
Obviously, the solution is to ensure that the compiler being used is compatible.

Related

How to avoid error when filling print, error evaluating expression?

Currently, I am working in JasperReport Server and iReport. The version of JasperReport 5.5.0 and iReport are 5.5.0. And the database is MYSQL.
I declared the variable Dr like the following where am_primeamt is coming from SQL query.
<variable name="Dr" class="java.lang.Double">
<variableExpression><![CDATA[($F{am_primeamt} > 0 ? $F{am_primeamt} : 0 )]]></variableExpression>
</variable>
And tried to show like following:
<textField pattern="#,##0.00">
<reportElement x="427" y="0" width="82" height="20" uuid="332ceda3-5237-40b5-a0ef-3aad009a7911">
<printWhenExpression><![CDATA[$V{Dr} != 0]]></printWhenExpression>
</reportElement>
<textElement textAlignment="Right"/>
<textFieldExpression><![CDATA[$V{Dr}]]></textFieldExpression>
When I am trying to see the preview it's showing the following error:
Error filling print... Error evaluating expression :      Source text : $V{Dr} != 0
net.sf.jasperreports.engine.fill.JRExpressionEvalException: Error evaluating expression :      Source text : $V{Dr} != 0      at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:244)      at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:591)      at net.sf.jasperreports.engine.fill.JRCalculator.evaluate(JRCalculator.java:559)      at net.sf.jasperreports.engine.fill.JRFillElement.evaluateExpression(JRFillElement.java:1016)      at net.sf.jasperreports.engine.fill.JRFillElement.evaluatePrintWhenExpression(JRFillElement.java:795)      at net.sf.jasperreports.engine.fill.JRFillTextField.evaluate(JRFillTextField.java:482)      at net.sf.jasperreports.engine.fill.JRFillElementContainer.evaluate(JRFillElementContainer.java:259)      at net.sf.jasperreports.engine.fill.JRFillBand.evaluate(JRFillBand.java:456)      at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillColumnBand(JRVerticalFiller.java:2057)      at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillDetail(JRVerticalFiller.java:778)      at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReportStart(JRVerticalFiller.java:288)      at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:151)      at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:932)      at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:845)      at net.sf.jasperreports.engine.fill.JRFiller.fill(JRFiller.java:87)      at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:446)      at net.sf.jasperreports.engine.JasperFillManager.fill(JasperFillManager.java:276)      at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:745)      at com.jaspersoft.ireport.designer.compiler.IReportCompiler.run(IReportCompiler.java:891)      at org.openide.util.RequestProcessor$Task.run(RequestProcessor.java:572)      at org.openide.util.RequestProcessor$Processor.run(RequestProcessor.java:997)  Caused by: java.lang.ClassCastException: java.math.BigDecimal cannot be cast to java.lang.Double      at gl_transaction_1454989470091_439976.evaluate(gl_transaction_1454989470091_439976:363)      at net.sf.jasperreports.engine.fill.JREvaluator.evaluate(JREvaluator.java:231)      ... 20 more 
Print not filled. Try to use an EmptyDataSource...
Edited:
Language is set java from the beginning and that showed the error like this. After making it groovy, it solved my problem.
The accepted answer does not address the problem and since its upvoted with deleted users (ask your-self why) even if question does not have complete mcve I have decided to answer to help future viewer to understand the issue. The accepted answer has been deleted by moderators, but question remains and has indicated the solution of setting language groovy
The issues is:
java.lang.ClassCastException: java.math.BigDecimal cannot be cast to
java.lang.Double
This is most probably caused by that the field $F{am_primeamt} is defined as java.math.BigDecimal
<field name="am_primeamt" class="java.math.BigDecimal">
<fieldDescription><![CDATA[]]></fieldDescription>
</field>
The correct solution would be to change the current variable declaration to same class or return declared class
Same class
<variable name="Dr" class="java.math.BigDecimal">
<variableExpression><![CDATA[($F{am_primeamt}.doubleValue() > 0 ? $F{am_primeamt} : new java.math.BigDecimal(0) )]]></variableExpression>
</variable>
Note: printWhenExpression not to be changed to example $V{Dr}.doubleValue() != 0
Declared class
<variable name="Dr" class="java.lang.Double">
<variableExpression><![CDATA[($F{am_primeamt}.doubleValue() > 0 ? $F{am_primeamt}.doubleValue() : 0d )]]></variableExpression>
</variable>
Why does groovy works?, it does automatic conversion using java.lang.Number and use operator overloading to allow direct mathematical operations on the BigDecimal object see http://www.groovy-lang.org/, but before you choose it instead of java its better to understand why.......

Get first letter of first and last row in Jasper Reports table

I am using JasperSoft Studio in Eclipse to generate a signup sheet for a church. The page header has the label of what last names will be on the page. So page 1 will have A-D, if the page starts with an A, and ends with a D.
This is turning out to be very complicated for such an easy task. I just want to read what the last_name field is in the first and last row of every page, take the first letter of it, and then stick it in the header.
Any ideas are welcome, I am stumped.
To get the first and last value of a field in a page you use variables with resetType and set the correct evalutationTime on the textField (You will need to use 2 textField aligning them correctly one next to the other)
This example will show how to get the first and last value of the field $F{Last_Name} on every page
First value of a field in the page
The resetType on your variable will be resetType="None"
<variable name="firstValueOnPage" class="java.lang.String" resetType="None">
<variableExpression><![CDATA[$F{Last_Name}]]></variableExpression>
</variable>
and in the textField, use the variable with evalution="Now" (that is default so no tag needed)
<textField>
<reportElement x="30" y="19" width="100" height="20" uuid="e6421031-6db7-4fd9-995f-94cef2eb3621"/>
<textFieldExpression><![CDATA[$V{firstValueOnPage}]]></textFieldExpression>
</textField>
Last value of a field in the page
The resetType of your variable is resetType="Page"
<variable name="lastValueOnPage" class="java.lang.String" resetType="Page">
<variableExpression><![CDATA[$F{Last_Name}]]></variableExpression>
</variable>
and in the textField use the variable evaluationTime="Page"
<textField evaluationTime="Page">
<reportElement x="170" y="19" width="100" height="20" uuid="9100baa5-0095-4dc3-ac79-2cd87562a92d"/>
<textFieldExpression><![CDATA[$V{lastValueOnPage}]]></textFieldExpression>
</textField>
To get only the first char of first and last value I see that you have already figured it out, but to complete the answer the textFieldExpression would be
<textFieldExpression><![CDATA[($V{firstValueOnPage}!=null&&$V{firstValueOnPage}.length()>0)?String.valueOf($V{firstValueOnPage}.charAt(0)).toUpperCase():""]]></textFieldExpression>
Now just put the two textField's next to each other (align them correctly) and you will have the desired result.
Some additional information to learn more about resetType and evalutationTime (from jasper report api 6.2.0)
resetType
None - The variable is incremented with every record during the iteration through the data source
Report - The variable never gets incremented during the report filling process.
Page - The variable is incremented with each new page.
Column - The variable is incremented with each new column.
Group - The variable is incremented every time the group specified by the incrementGroup attributes breaks
EvalutationTime
Auto Evaluation time indicating that each variable participating in
the expression should be evaluated at a time decided by the engine.
Band The element will be evaluated at band end.
Column A constant specifying that an expression should be evaluated after each column is filled.
Group A constant specifying that an expression should be evaluated after each group break.
Master Used for elements that are evaluated at the moment the master report ends.
Now A constant specifying that an expression should be evaluated at the exact moment in the filling process when it is encountered.
Page A constant specifying that an expression should be evaluated after each page is filled.
Report A constant specifying that an expression should be evaluated at the end of the filling process.
Report is ordered by Last_Name therefore we can use calculation Lowest and Highest
define variables:
<variable name="lowestFirstLetter" class="java.lang.String" resetType="Page" calculation="Lowest">
<variableExpression><![CDATA[$F{Last_Name}.substring(0,1)]]></variableExpression>
</variable>
<variable name="highestFirstLetter" class="java.lang.String" resetType="Page" calculation="Highest">
<variableExpression><![CDATA[$F{Last_Name}.substring(0,1)]]></variableExpression>
</variable>
and put textFields with evaluationTime="Page" into PageHeader band
<pageHeader>
<band height="35" splitType="Stretch">
<textField evaluationTime="Page">
<reportElement x="80" y="15" width="100" height="20" uuid="72af3431-eb3d-4f40-993b-4f0733e779cd"/>
<textFieldExpression><![CDATA[$V{lowestFirstLetter}]]></textFieldExpression>
</textField>
<textField evaluationTime="Page">
<reportElement x="260" y="15" width="150" height="20" uuid="0452517b-5066-4f8a-af6b-f941f1d3c1cb"/>
<textFieldExpression><![CDATA[$V{highestFirstLetter}]]></textFieldExpression>
</textField>
</band>
</pageHeader>
Good luck

Jasper sub-reports of sub-reports - programmatically

There are many examples of running sub-reports in Jasper on the web, but nobody seems to have had the problem that I have, when running a sub-report that contains another sub-report.
We store our report definitions in a Relational Database, and generate and run the reports out of a java service. We only use the GUI to design and test each report, to start with.
The reports are compiled and filled at runtime, and I can cause a sub-report to run, by using the well documented feature of adding the compiled sub-report to the main report at fill time using the report expression to use a sub-report as a parameter.
That is all fine. However, how can I fill the first sub-report with the compile output of the next sub-report down the tree?
To explain a little further, in JasperStudio, I can do this in the main report:
<subreport>
<reportElement x="4" y="100" width="547" height="310" uuid="f9364882-a530-475d-97af-8d6d2d47ae57"/>
<subreportParameter name="INSP_ID">
<subreportParameterExpression><![CDATA[$F{jobid}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<subreportExpression><![CDATA["InspectionFrogSubReport.jasper"]]></subreportExpression>
</subreport>
Then in the first sub report, to refer to the next one, I can do this:
<subreport>
<reportElement x="280" y="56" width="270" height="294" uuid="b4cbe376-1b54-471c-a6d4-0d45afeab2c8"/>
<subreportParameter name="FROG_ID">
<subreportParameterExpression><![CDATA[$F{frog_id}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<subreportExpression><![CDATA["InspectionDamageSubReport.jasper"]]></subreportExpression>
</subreport>
So, when I preview the mian, it fills the first sub, and then the next sub, no problem.
However, to fill from Java method, I change the main sub-report expression to:
<subreport>
<reportElement x="4" y="100" width="547" height="310" uuid="f9364882-a530-475d-97af-8d6d2d47ae57"/>
<subreportParameter name="INSP_ID">
<subreportParameterExpression><![CDATA[$F{jobid}]]></subreportParameterExpression>
</subreportParameter>
<connectionExpression><![CDATA[$P{REPORT_CONNECTION}]]></connectionExpression>
<subreportExpression><![CDATA["$P!{SUB1}"]]></subreportExpression>
</subreport>
Then in my code:
// Compile sub report
InputStream childStream = new ByteArrayInputStream(subReport.getChildXml().getBytes());
JasperReport compiledChild = JasperCompileManager.compileReport(childStream);
// Compile Main report
InputStream xmlStream = new ByteArrayInputStream(report.getXml().getBytes());
JasperReport compiledReport = JasperCompileManager.compileReport(xmlStream);
// Build report parameter map
Map<String, Object> params = new HashMap<>();
params.put("SUB1", compiledChild);
// Fill main report
JasperPrint jasperPrint = JasperFillManager.fillReport(compiledReport, params, conn);
so far, so good. However, how do I pass the sub-sub-report into the sub-report. I cannot use 'fillReport' as the sub report will have no master record to work on until the main report runs.
Pass subSubReport as a param to supReport.
in java code:
params.put("SUB_SUB_REPORT", compiledSubSubreport);
in main report template xml:
<subreportParameter name="SUB_SUB_REPORT">
<subreportParameterExpression><![CDATA[$P{SUB_SUB_REPORT}]]></subreportParameterExpression>
</subreportParameter>
this is what you want?

Grouping by parameter value in jasper

Well, I don't know, maybe I'm missing something, but I've been trying to group data in a jasper report, but so far the grouping appears only if the group expression is a field. Is it possible to group data by parameter value instead of field value? i.e., something like
<groupExpression><[!CDATA[$P{some_param}]]></groupExpression>
instead of
<groupExpression><[!CDATA[$F{some_field}]]></groupExpression>
in the .jrxml file?
Is it possible to group data by parameter value instead of field value?
Yes, it is, just like you mentioned. You would have no syntax errors and the report would be generated.
The problem is that it may not bring what you're expecting. The group bands are usually printed every time the "groupExpression" changes. So basically this parameter needs to be associated with something that will change during the report generation (for example, filling a parameter of a subreport with a field in way that this subreport uses this paramater as a group expression). And of course, it needs to be associated with something that makes sense and bring you the desirable behavior.
You can have something like this in your subreport:
...
<parameter name="START" class="java.util.Date"/>
<parameter name="END" class="java.util.Date"/>
...
And something like this in a detail band of your "super" report:
<subreport>
<reportElement x="0" y="10" width="555" height="200" uuid="ac2c99da-f595-4498-a518-2bfb1f31b73c"/>
<subreportParameter name="START">
<subreportParameterExpression><![CDATA[$F{start}]]></subreportParameterExpression>
</subreportParameter>
<subreportParameter name="END">
<subreportParameterExpression><![CDATA[$F{end}]]></subreportParameterExpression>
</subreportParameter>
...
</subreport>
Just notice I'm assuming the fields $F{end} and $F{start} are also "java.util.Date" objects.

Pass a variable from table to parent report

I have one child table inside report.. Inside that table I have a variable that I want to use in parent report. Is it possible to pass it from table up to parent report?
Thank you
You can pass the final value of a table subdataset variable back to the main report. The value is returned at the end of each table instantiation.
The report JRXML would look something like the following. You can use a different calculation type if you want to sum/aggregate the returned value in the main report.
<subDataset name="TableDataset">
<variable name="SubdatasetVariable" class="java.lang.Integer" ../>
</subDataset>
<variable name="AVariable" class="java.lang.Integer" calculation="System"/>
<jr:table >
<datasetRun subDataset="TableDataset">
<returnValue fromVariable="SubdatasetVariable" toVariable="AVariable" calculation="Nothing"/>
..