Using a POJO as an iReport data source - java

I have a POJO that compiles data from various sources into a single object. The object is instantiated with a single parameter. Example:
Invoice inv=new Invoice(1239);
This will bring back a complete invoice containing other POJOs populated with data from various sources (such as the billing and shipping addresses as Address objects).
Can I use this as a data source within iReport?

You could try use a JRMapCollectionDataSource from which you can build a DataSource from a collection.
You could take the values from the POJO object and place them into a collection if possible.
Here is some sample code for constructing a DataSource.
Collection<Map<String, Object>> myColl = new ArrayList<Map<String,Object>>();
Map<String, Object> map1 = new HashMap<String, Object>();
map1.put("Field1","Value1");
map1.put("Field2","Value2");
map1.put("Field3", someObject);
myColl.add(map1);
JRMapCollectionDataSource source = new JRMapCollectionDataSource(myColl);
Another option would be to create a custom datasource by implementing JRRewindableDataSource or JRDataSource.

Related

How to create mongodb collection in spring boot without using pojo class?

I have a spring boot app with a MongoDB connection. On using the POJO/Model class with #Document(Collection = "CompanyDetails"), it successfully creates the collection in MongoDB after "POSTMAPPING" and the result goes inside the CompanyDetails collection as expected.
I have used controller, service, repository, and used the Map<String, Object> in parenthesis of the repository rather than using POJO class.
Controller:
#PostMapping("/addRecords")
public Map<String, Object> addCompanyDetails(#RequestBody Map<String, Object> companyDetails) {
return companyDetailsService.addCompanyDetails(companyDetails);
}
Service:
#Service
public class CompanyDetailsService {
#Autowired
CompanyDetailsRepository companyDetailsRepository;
public Map<String, Object> addCompanyDetails(Map<String, Object> companyDetails) {
return companyDetailsRepository.insert(companyDetails);
}
}
Repository:
#Repository
public interface CompanyDetailsRepository extends MongoRepository<Map<String, Object>, String> {}
My requirement is to create a collection without a POJO class. Because, the fields are not fixed(while inserting records). So, I can't declare fields in the POJO class & generate a getter setter.
As I'm not using the POJO class, when I POST record, it creates a collection with the name "map" & insert records inside that.
But, expected was to create "CompanyDetails" collection & store data inside that.
Yes, people using MongoDB faced this issue as MongoDB is a schemaless database and creating POJO will be difficult. So, here is the solution for such use-cases.
Firstly, you can use the MongoClient to connect with your database. Check out this document for your reference: Connect to MongoDB
Secondly, you can create databases and collections using that `mongoClient object. Check out this document for your reference Create database and collection
Finally, you can use some generic objects like HashMap or BasicDBObject to perform your CRUD operation

How do can I edit List of Immutable objects in Vaadin?

MyObj is immutable so it is impossible to edit them, however I should be able to swap them in the list. How should I achieve this?
Here is my Vaadin grid:
List<MyOBj> data = new ArrayList<>();
data.add(new MyObj(..));
data.add(new MyObj(..));
Grid<MyOBj> grid = new Grid<>(MyOBj.class);
grid.setItems(data);
grid.getEditor().setEnabled(true);
grid.addColumn(MyObj::someField).setCaption("someField");
Would MyObj mutable I would just bind the editor:
Binder<MyOBj> binder = grid.getEditor().getBinder();
Binding<MyOBj, Boolean> binding = binder.bind(..binding setters/getter..);
column.setEditorBinding(binding);
Now I am looking for something like this:
Binder<MyOBj> binder = grid.getEditor().getBinder();
Binding<MyOBj, Boolean> binding = binder.bind(..creating new Object and put on the given index of the list..);
column.setEditorBinding(binding);
Is that possible somehow?
Two general solutions form the top of my mind:
Define a mutable DTO that you use while the object is being edited. Once the user saves their edit, you create a new immutable MyObj instance based on the current values in the DTO.
Change your Binder to edit a reference to a MyObj instead of directly editing a MyOjb. A practical way of doing this, albeit with a small semantic mismatch, is to do Binder<AtomcReference<MyObj>>.

Generate jasper report using singe java bean

i have requirement to create order declaration report, i am using jasper studio to create the jasper template. in that template i have order id, customer details and his address, with these details i have to create a report.
i have below jasper report code
JasperCompileManager.compileReportToFile("src/main/resource/orderDeclarationForm.jrxml");
JasperPrint jasperPrint = JasperFillManager.fillReport("src/main/resource/orderDeclarationForm.jasper", new HashMap<String, Object>(), new JRTableModelDataSource(getTableModelData()));
// JasperExportManager.exportReportToPdfFile("resource/orderDeclarationForm.jrprint");
JasperExportManager.exportReportToPdfFile(jasperPrint, "src/main/resource/orderDeclarationForm.pdf");
but instead of JRTableModelDataSource i have to pass java bean class so the jasper engine has to take the data from one single java bean, i have gone through javabean as datasource where it takes list of beans, but my requirement is only one bean which has order details. please advice me on this
If you only need one instance of a bean to be passed to JasperFillManager.fillReport method, then it makes sense to pass them as parameters as long as their count is feasible (in your case its only 3).
Map<String,Object> params = new HashMap<String,Object>();
params.put("orderId", xxx);
params.put("customerDetails", xxx);
params.put("address", xxx);
Afterwards, pass this params Map object:
JasperPrint jasperPrint = JasperFillManager.fillReport("src/main/resource/orderDeclarationForm.jasper", params, new JRTableModelDataSource(getTableModelData()));
Please check this link for more info on how to read Parameters from within your .jrxml file.
Thanks.

Creating Map or Set using GSON

I am using Google's GSON library and want to create a JSON which looks something like this:
{
"teamSet":[],
"classificationMap" : {}
}
Notice that [] and {} are empty Set and Map respectively and are not surrounded with double quotes.
I want to create this Json using the GSON add/addproperty method and not by converting a Java class into JSON using the Gson.toJson() method. The business use-case restricts me from creating specific Java classes as the JSON structure may change overtime. So I cannot use a class like this as this would rigidly tie a JSON structure with a concrete class
class Linkage{
private Set<String> teamSet;
private Map<String, String> classificationMap;
// getter, setter methods follow
...
}
When I use the GSON.addproperty(genericObject, type), it is appending double quotes around [] and {}. I am using couchbase for my DB requirements and the double quotes around [] and {} makes couchbase treat them as string and not as Set/Map. This renders my Map-Reduce views useless and buggy :(
Please let me know if its possible to create such a JSON without having to tie it up with a concrete JAVA class. Thanks !
My current code looks like this:
// create types
Type setType = new TypeToken<Set<String>>() {}.getType();
Type mapType = new TypeToken<Map<String, String>>() {}.getType();
Gson GSON = new Gson();
Set<String> teams = new HashSet<String>();
Map<String, String> classificationMap = new HashMap<String, String>();
JsonObject linkageJson = new JsonObject();
linkageJson.addProperty("teamSet", GSON.toJson(teams, setType));
linkageJson.addProperty("classificationMap", GSON.toJson(classificationMap, mapType));
In the 2.x line of the couchbase java sdk, there is the JsonObject class that could have fit your need.
It is perfect to create Json "by hand" and still have a simple generic object representation, and is the official way of putting json into the database via the sdk.
It would go like this :
JsonObject obj = JsonObject.create();
obj.put("teamSet", JsonArray.from(new ArrayList(teams)))
.put("classificationMap", JsonObject.from(classificationMap));
Granted this is a little bit contrived because arrays and sub-objects can only be constructed from respectively List<?> and Map<String, ?> factory methods. Also the class support a limited set of value types (no custom classes, only String, Number, Boolean, etc...).
i feel somewhere it is storing it toString() representation.
Please refer below link, it might help you.
click here

Copy HashMap of different type

How can I copy content of one HashMap<String,AddressDTO> to another HashMap<String,AddressBO> of a different type. There is no
inheritance between AdressDTO and AddressBO ,both are POJOs with the same set of attributes:
AddressDTO addDTO = new AddressDTO();
addDTO.setAdd1("add1");
addDTO.setAdd2("add2");
addDTO.setAddtype("pri");
addDTO.setCity("city");
Map<String,Object> map1 = new HashMap<String,Object>();
map1.put("primary", addDTO);
Map<String,Object> map2 = new HashMap<String,Object>(map1);
AddressBO addnew = (AddressBO) map2.get("primary");
//this will give me runtime error AddressDTO cannot be cast to AddressBO
System.out.println(addnew.getAdd1());
System.out.println(addnew.getAdd2());
System.out.println(addnew.getAddtype());
You can loop through the results of entry set which will give you the key value pairs and allow you to copy.
Also, HashMap takes a map. Probably other maps do too.
You cannot cast one Object to another based on field similarity only. You should use inheritance, or use some kind of transformer to create AddressBO from AddressDTO
If both Object contains exactly the same fields, there is no need for two classes.
There are various tools available that will use reflection to copy the values.
Alternatively you could just set the reference in the new map to be the same as the old map (then they will both share the same HashMap).
But it sounds like your real problem is mapping from the DTO to the BO.
For example if you create a constructor for the BO that accepts a DTO and creates a new BO from it then you could just do:
for (Entry<String, DTO> e: map1) {
map2.put(e.getKey(), new BO(e.getValue()));
}

Categories

Resources