JasperReports nested loop - java

The goal is the following structure
Static Text
--------------------
Category 1
SubCategory 1_1
SubCategory 1_2
...
Category 2
SubCategory 2_1
....
...
--------------------
StaticText
To get the dynamic data i use the following bean structure
public class BeanFactory {
public static Collection getVehicleData() {return the Collection}
}
Category class
public class VehicleData {
private String category;
private List<WarningData> warnings;
}
The WarningData class is a POJO. So can anyone give me a hint how i can get this kind of structure?
I tried to use two data set, one is using the beanfactory to create the data and one should use the vehicledata class to get the warningdata. But this did not work for me.
I tried to group it. But i don't know how to access the warning data
Should i use a table or a list component from the iReport Designer?
Can i use a loop in the expression editor?
Update
To make this clear. How can i iterate over the subcategories? I succeed with the iteration over the categories, but i don't know how i iterate for every category over the subcategories.

The solution was in a kind of the hint from Lisa's comment. Instead of the data structure in the question, i created a "flat" structure like the following:
public class VehicleData2 {
private String category;
private String categoryIconPath;
private String iconPath;
private String headline;
private String warning;
}
The last three attributes was encapsuled in a new class WarningData. But I was not able to iterate throw this list of warning data, so in my solution there is e. g. redundancy in the category. But with this kind of structure it is possible to use a report group for the categories and to put the warning data into the detail part of the jasperreport.

The only two ways to iterate on subdata of a record seem to be Subreports and Tables.
Each datasource is an iterator through a flat list. Your report contains only one notion of repetition, that is, repeating a Detail section for each record in a datasource. Tables and Subreports both have their own datasources (which may well depend on the current iteration of the containing report), and repeat their Detail-sections accordingly. Since they can be nested, jasper theoretically allows arbitrary looping as required. Just that you'll need to introduce a subreport or a table for each loop:
The Detail section of your root record
The Detail section of a Subreport
The Detail section of a Table

Related

How to selectively load hibernate entity while still initializing (not loading) lazy collection

Consider following simple entity model
class Order{
int id;
String description;
//one to one eager load with join column specified
Detail details;
//one to many lazy load with mapped by specified
Collection<Item> items;
}
class Detail{
}
class Item{
String name;
//reference to order
}
Now, let's say the requirement is to load all the orders with item details by some criteria (e.g. description matching something). Simple, i write a hql like "from Order where description...". This loads 1000 entities for example and item collection is lazy loaded. I force load them within the session by calling size.
This of course led to a N+1 problem so i decided to use batch fetching for items. Just added the batch size annotation on item collection and much fewer queries as expected.
However, i am not interested in 'detail' at all but since it is a one to one eager load, there is one query per Order to load this always. I simply want to do away with these queries.
To solve this, i try to do a select without details but i am not sure how to include items (collection) in the query so that it is loaded exactly in the same way as if i was selecting all (that is, lazy loaded which then can utilize batch size on later calls). Some suggestions are to use join in the where clause but that initializes my collection with empty array list (and not with PersistentBag as is the case with Lazy loading).
Looking for solutions.
One possible solution is the following:
Create a POJO which will contain a query result. Example:
public class OrderResult {
private String description;
private String itemName;
// ... more fields, if any
public OrderResult(String desc, String itemName) {
this.description = desc;
this.itemName = itemName;
}
// getters & setters
}
Create a JPQL query using a constructor expression as:
List<OrderResult> resultList = entityManager.createQuery("SELECT NEW OrderResult(o.description, i.name) FROM Order o JOIN o.items i where <condition>", OrderResult.class).getResultList();
So you'll get a list of instances of OrderResult containing only the information you're interested in.
NOTE 1: You're talking of HQL, but HQL is the Hibernate specific legacy query language. As Hibernate is an implementation of JPA, and you tagged your question with JPA, this solution should work in your environment too.
NOTE 2: In the solution, I am using the so called constructor expression of JPQL which is defined using NEW in the select clause. The argument to the NEW operator must be a fully qualified class name,e.g., if you put the OrderResult class in a package com.mycompany.myproject.order, then the expression should look like:
SELECT NEW com.mycompany.myproject.order.OrderResult(...) FROM ...
NOTE 3: This is just to give you a hint how to implement the solution and should be considered as pseodo code.

Jdo (datanucleus) integer_idx column and databinding

I've been trying to do a simple one to many object binding in DataNucleus JDO. It's just two classes (i stripped a simple fields):
#PersistenceCapable(table="ORDER",schema="mgr")
public class Order {
#PrimaryKey(column="id")
#Persistent(valueStrategy=IdGeneratorStrategy.NATIVE,column="id")
private Long id;
#Persistent(defaultFetchGroup="false",column="customer_id")
#Element(column="customer_id")
private Customer customer;
}
And a class Customer having a list of orders
#PersistenceCapable(table="customer",schema="mgr",identityType=IdentityType.DATASTORE)
#DatastoreIdentity(strategy=IdGeneratorStrategy.NATIVE)
public class Customer {
#PrimaryKey
#Persistent(valueStrategy=IdGeneratorStrategy.NATIVE,column="id")
private Long id;
#Persistent(mappedBy="customer")
private List<Order> orders;
}
The database table setup is extremely simple(a table for customer and a table for orders with a foreign key (customer_id) referencing customer). Yet, when i try to insert some orders for customer i receive an error
javax.jdo.JDODataStoreException: Insert of object
"test.Order#17dd585" using statement "INSERT INTO
ORDER
(USER_COMMENT,ORDER_DATE,STATUS,CUSTOMER_ID,ORDERS_INTEGER_IDX)
VALUES (?,?,?,?,?)" failed : Unknown column 'ORDERS_INTEGER_IDX' in
'field list'
Somehow DataNucleus is assuming, there is a column ORDERS_INTEGER_IDX (such column does not exist in the database). The only idea, that came to my mind is http://www.datanucleus.org/products/datanucleus/jdo/metadata_xml.html
In some situations DataNucleus will add a special datastore column to
a join table so that collections can allow the storage of duplicate
elements. This extension allows the specification of the column name
to be used. This should be specified within the field at the
collection end of the relationship. JDO2 doesnt allow a standard place
for such a specification and so is an extension tag.
So cool! 'in some situations'. I have no idea how to make my situation not to be a subset of 'some situations' but I have no idea, how to get this working. Perhaps someone has allready met the "INTEGER_IDX" problem? Or (it is also highly possible) - im not binding the data correctly :/
So you create the schema yourself. Your schema is inconsistent with metadata. You run persistence without validating your metadata against schema, and an exception results. DataNucleus provides you with SchemaTool to create or validate the schema against your metadata, so that would mean that you can detect the problem.
You're using an indexed list, so it needs an index for each element (or how else is it to know what position an element is in?). How can it assume there is an index? well it's a thing called the JDO spec (publically available), which defines indexed lists. If you don't want positions of elements storing then don't use a List (the Java util class for retaining the position of elements) ... so I'd suggest using a Set since that doesn't need position info (hence no index).
You also have a class marked as datastore identity, and then have a primary-key. That is a contradiction ... you have one or the other. The docs define all of that, as well as how to have a 1-N List relation ("JDO API" -> "Mapping" -> "Fields/Properties" -> "1-N Relations" -> "Lists" or "Sets")

PlayFramework get field from model select

Since the play documentation on models is terrible I'll ask here. I have the basic code;
public static void Controller() {
List<Item> item = Item.find("SELECT itemname,id FROM Item WHERE itembool = true ORDER BY itemcreated ASC LIMIT 0,1").fetch();
if ( item == null ) {
notFound();
}
}
What I'm trying to do is get the value for 'itemname' returned for the first value returned from an SQL query (The real query is much more complicated and other things so it can't be replaced with methods). I can get the entire first object with item.get(0) but I can't figure out how to get the value of 'itemname' as a string and it doesn't seem to be documented anywhere.
Edit
Probably should have mentioned in the original question, I need to retrieve by field name, not index. I.E. I can't do items.get(0)[0]; I need to do items.get(0)['itemname'];
The documentation explains this if you read it, in here. Hibernate doesn't use SQL, but JPQL, which has a different syntax as it works with objects, not individual fields.
What you want to do can be achieved in two ways (both in the documentation):
List<Item> item = Item.find("SELECT i FROM Item i WHERE i.itembool = true ORDER BY i.itemcreated ASC").fetch(1);
List<Item> item = Item.find("itembool = true ORDER BY itemcreated ASC").fetch(1);
EDIT:
On the retrieval part, you will get a list of Item, so you can just access the field directly on the object:
item.get(0).getItemName();
Since Play uses Hibernate under the hood, you need to take a look at Hibernate's documentation.
In particular, SELECT itemname,id ... yields Object[] rather than Item, so that you can get itemname as follows:
List<Object[]> items = ...;
String itemname = items.get(0)[0];
well if you have to do a select itemname,id ..., you would not be able to do a items.get(0)["itemname"] because as axtavt and Pere have mentioned, you would get a Object[] back. You can instead create another (perhaps immutable) entity class that can be used in this query. Please refer to hibernate documentation for details. You can then model the entity based on your query requirements and use it to fetch information, thus letting hibernate handle all the magic number game for you. That ways, you would have a bean with filled up values that you can use to map back to your model class if you like.
HTH!

Lucene/Hibernate Search - Query associated collections?

I'm writing a Seam-based application, making use of JPA/Hibernate and Hibernate Search (Lucene). I have an object called Item that has a many-to-many relation to an object
Keyword. It looks like this (some annotations omitted):
#Indexed
public class Item {
...
#IndexedEmbedded
private List<Keyword> keywords;
...
}
#Indexed
public class Keyword {
...
#Field
private String value;
...
}
I'd like to be able to run a query for all Item object that contain a particular keyword value. I've setup numerous test objects in my database, and it appears the indexes are being created properly. However, when I create and run a query for "keywords.value" = <MY KEYWORD VALUE> I always get 0 results returned.
Does Hibernate Search/Lucene have the ability to run queries of this type? Is there something else I should be doing? Are there additional annotations that I could be missing?
Hibernate Search is perfectly suited for that kind of queries; but it can be done in a simpler way.
On your problem: text indexed by Hibernate Search (Lucene) is going to be Analysed, and the default analyser applies:
Lower casing of the input
Splitting in separate terms on whitespace
So if you're defining the queries as TermQuery (I'm assuming that's what you did, as it's the simplest form), then you have to match against the lower case form, of a token (with no spacing).
Bearing this in mind, you could dump all your keywords in a single Blob String on the Item entity, without needing to map it as separate keywords, chaining them in a single string separated by whitespaces.

solrj: how to store and retrieve List<POJO> via multivalued field in index

My use case is an index which holds titles of online media. The provider of the data associates a list of categories with each title. I am using SolrJ to populate the index via an annotated POJO class
e.g.
#Field("title")
private String title;
#Field("categories")
private List<Category> categoryList;
The associated POJO is
public class Category {
private Long id;
private String name;
...
}
My question has two parts:
a) is this possible via SolrJ - the docs only contain an example of #Field using a List of String, so I assume the serialization/marshalling only supports simple types ?
b) how would I set up the schema to hold this. I have a naive assumption I just need to set
multiValued=true on the required field & it will all work by magic.
I'm just starting to implement this so any response would be highly appreciated.
The answer is as you thought:
a) You have only simple types available. So you will have a List of the same type e.g. String. The point is you cant represent complex types inside the lucene document so you wont deserialize them as well.
b) The problem is what you are trying is to represent relational thinking in a "document store". That will probably work only to a certain point. If you want to represent categories inside a lucene document just use the string it is not necessary to store a id as well.
The only point to store an id as well is: if you want to do aside the search a lookup on a RDBMS. If you want to do this you need to make sure that the id and the category name is softlinked. This is not working for every 1:n relation. (Every 1:n relation where the n related table consists only of required fields is possible. If you have an optional field you need to put something like a filling emptyconstant in the field if possible).
However if these 1:n relations are not sparse its possible actually if you maintain the order in which you add fields to the document. So the case with the category relation can be probably represented if you dont sort the lists.
You may implement a method which returns this Category if you instantiate it with the values at position 0...n. So the solution would be if you want to have the first category it will be at position 0 of every list related to this category.

Categories

Resources