Setting list from drools decision table - java

I am using drools for implementing certain condtion.I don't know how to set the
arraylist of the bean in action from drools decision table.For example following is my class.
public class Dog implements Serializable{
private String id;
private List<String> names;
}
My decision table should set the list of names based on the id paseed.How to implement this?
Conditon Action
d:Dog
id ???(what needs to be done here)
1 "tom","jack","pearl"

This can be done in the usual way.
Condition Action
d:Dog d.getNames()
id addAll(Arrays.asList($param))
Match id! Add some names!
1 "tom","jack","pearl"
You'll have to import Arrays or use the full class name.

If you used Spreadsheet File (.xlsx or .xls) then you can try this:
pojo calss:
public class CategoryEntity {
private String type;
private String allAction;
private List<String> actionList; // list
// Getters and Setters
}
And Spreadsheet File like this:

Related

How to resolve "Should not reach the end of iterator" while trying to use Query by example of Spring for Cosmos DB

I have a requirement of using a java model which will have couple of attributes but some of them will have values and some of them will not have and this is not fixed. For example if it has 4 attribute 3 may have values while passing it to the controller method or it may so happen 2 of them will have values but then rest of the attributes will be null. So to handle this i choose to use Query by example of spring , but i am getting
java.lang.IllegalArgumentException : "Should not reach the end of iterator"
I am trying to fetch data from a Azure CosmosDB. Below is the code i have used
ExampleMatcher macther = ExampleMatcher.matching().withIgnoreNullValues();
Example<RequestModel> exampleQ = Example.of(new RequestModel(
req.getEmp(), // these are the attributes which can have alternatively values or can be empty
req.getBase(),
req.getSeat(),
req.getRent()
),matcher);
sampleRepo.findByEmpOrBaseOrSeatOrRent(exampleQ ); // here i am getting the exception
The Repository
public interface SampleRepo extends CosmosRepository<TableA,String>,BaseContainerRepo{
}
The container
#Container(containerName= "${container-tableA}")
public class TableA extends BaseContainer{
}
Base model class
public class BaseContainer{
#Id
private String id;
private Inetger emp;
#PartitionKey
private String key;
private String base;
private String eqp;
}
The base container repo
public interface BaseContainerRepo{
List<BaseContainer> findByEmpOrBaseOrSeatOrRent(Example<RequestModel> exampleQ);
}
Can anyone please let me know where i am doing it wrong .

How to update duplicate entries in MongoDB with Spring Data

I have following entity-model which I'll save to my MongoDB:
#Document(collection = "googleplaygames")
#Component
public final class GooglePlayGame implements Serializable {
#Id
private String title;
private String genre;
private String price;
private LocalDate dateOfLastUpdate;
...
This code allows me to save duplicates Game objects. I found annotation #Indexed and rewrote code:
#Document(collection = "googleplaygames")
#Component
public final class GooglePlayGame implements Serializable {
#Indexed(unique=true)
private String title;
private String genre;
private String price;
private LocalDate dateOfLastUpdate;
...
Now if I'll try to save entity with same title, I'll receive org.springframework.dao.DuplicateKeyException. Fair enough.
And I found this "error" in logs while Spring Boot app is starting:
2020-06-26 13:26:52,303 WARN [restartedMain] org.springframework.data.mongodb.core.index.JustOnceLogger: Automatic index creation will be disabled by default as of Spring Data MongoDB 3.x.
Please use 'MongoMappingContext#setAutoIndexCreation(boolean)' or override 'MongoConfigurationSupport#autoIndexCreation()' to be explicit.
However, we recommend setting up indices manually in an application ready block. You may use index derivation there as well.
> -----------------------------------------------------------------------------------------
> #EventListener(ApplicationReadyEvent.class)
> public void initIndicesAfterStartup() {
>
> IndexOperations indexOps = mongoTemplate.indexOps(DomainType.class);
>
> IndexResolver resolver = new MongoPersistentEntityIndexResolver(mongoMappingContext);
> resolver.resolveIndexFor(DomainType.class).forEach(indexOps::ensureIndex);
> }
> -----------------------------------------------------------------------------------------
But I want to update the enity, if any of other fields are different. For example, if I have an entity with title "Dead Cells" and version "1.0" in my db, I want to update this entity if version now is "1.1". But code above doesn't allow me to do this.
So what is this error? And how to update entity (doesnt allow duplicate by title field, but allow to rewrite entity, if other fields were changed).
According to how you put the question, if you are updating a document, you shouldn't receive the DuplicateKeyException, this only occurs if you have another document with the index value duplicated. Check you are applying the save() method of your repository (as I presume you do) on and existent instance of a Mongo document.
If you want to control duplications, you could use a compound index. A compound index includes more than one field in its definition, so it's faster to make searches for including in the criteria the fields of the index. Including the unicity constraint you'll be able to forbid the duplication of such values in another documents.
Let's say, according to your example you want to avoid titles and genre duplication, then you could define an index as:
#Document(collection = "googleplaygames")
#CompoundIndex(def = "{'title':1,'genre':1}", unique = true)
#Component
public final class GooglePlayGame implements Serializable {
private String title;
private String genre;
private String price;
private LocalDate dateOfLastUpdate;
...
With this index, if you have a document:
{"title":"Pacman","genre":"arcade"}
And try to create a new document with the same values for title and genre you will get the DuplicateKeyException.
If you try to create a document:
{"title":"Pacman","genre":"mobile"}
The you will have two documents.

How to create Excel report with subtable with Jasper reports

I am using Jasper reports to create Excel file programmatically. I am using Java Data Source - a java class that implements JRDataSource interface. Up until now My Datasource returned a List of class instances that looked something like this:
public Class MyDataSource implements JRDataSource {
private Integer prop1;
private String prop2;
private String prop3;
...
// getters and setters omitted to save space
}
With this Data Source I was able to create a very nice excel table that looked:
prop1-Header prop2-Header prop3-Header...
----------------------------------------
prop1-value prop2-value prop3-value...
prop1-value prop2-value prop3-value...
...
But now MyDataSource class has additional property List<String>
public Class MyDataSource implements JRDataSource {
private Integer prop1;
private String prop2;
private String prop3;
private List<String> subvalues;
...
// getters and setters omitted to save space
}
So I need my excel to look like this
prop1-Header prop2-Header prop3-Header...
----------------------------------------
prop1-value prop2-value prop3-value...
Sub-header1 Sub-header2...
-----------------------
sub-value1 sub-value2....
....
prop1-value prop2-value prop3-value...
Sub-header1 Sub-header2...
-----------------------
sub-value1 sub-value2....
....
...
I managed to do that by concatenating The list into a single string, and it looks very similar to what I need. But I have no way of sorting and filtering on sub-value data. So, I need to actually make it as sub-list or sub-table. And this is my question - how to do this?
After searching for a while I found the solution. First of all, the is a very nice youtube video
How to fill Jasper Report Table using Collection of data in Java?
This video shows in greate detail how to pass from java code into report an additional collection besides your Datasource java class. This is done by doing something like this:
JRBeanCollectionDataSource detailBean = new JRBeanCollectionDataSource(getMySubvaluesINstancesList());
Map<String, Object> params = new HashMap<>();
params.put("DetailDataSource", detailBean);
jasperPrint = JasperFillManager.fillReport(jasperReport, params, ds);
Note the name "DetailDataSource". In your report, you will need to create a parameter with that name and declare it's type as net.sf.jasperreports.engine.data.JRBeanCollectionDataSource. After that, you build a table based on a dataset that you create based on that parameter. But this is a short description of the video referenced above.
However, that alone doesn't solve the problem yet. The remaining problem that collection passed as a parameter will only be rendered once and will not be rendered for each record of your datasource. So, what we need to do is to add our list property into our datasource class, the same way as described in the question:
public Class MyDataSource implements JRDataSource {
private Integer prop1;
private String prop2;
private String prop3;
private List<String> subvalues;
...
// getters and setters omitted to save space
}
After that in your report you will need to declare a field named "subvalues" and declare its type as java.util.List. And then change the definition of your Dataset that you created following the video referenced above. You will need to change JRDatasource expression from $P{yourParameterName} to new net.sf.jasperreports.engine.data.JRBeanCollectionDataSource($F{subvalues}) And bingo! your collection is part of a datasource and will be rendered for each record

AWS DynamoDBMapper save method keeps throwing `DynamoDBMappingException: not supported; requires #DynamoDBTyped or #DynamoDBTypeConverted`

I followed everything that is outlined here - https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys. But still no luck.
I have a DynamoDB table with a hash key and a sort key.
Here is my entity class RecentlyPlayed.class
#DynamoDBTable(tableName="some-table")
public class RecentlyPlayed {
#Id
private RecentlyPlayedId recentlyPlayedId;
// ----- Constructor methods -----
#DynamoDBHashKey(attributeName="keyA")
// Getter and setter
#DynamoDBRangeKey(attributeName="keyB")
// Getter and setter
}
Here is my key class RecentlyPlayedId.class
public class RecentlyPlayedId implements Serializable {
private static final long serialVersionUID = 1L;
private String keyA;
private String keyB;
public RecentlyPlayedId(String keyA, String keyB) {
this.keyA = keyA;
this.keyB = keyB;
}
#DynamoDBHashKey
// Getter and setter
#DynamoDBRangeKey
// Getter and setter
}
Here is my repository interface RecentlyPlayedRepository
#EnableScan
public interface RecentlyPlayedRepository extends CrudRepository<RecentlyPlayed, RecentlyPlayedId> {
List<RecentlyPlayed> findAllByKeyA(#Param("keyA") String keyA);
// Finding the entry for keyA with highest keyB
RecentlyPlayed findTop1ByKeyAOrderByKeyBDesc(#Param("keyA") String keyA);
}
I am trying to save an object like this
RecentlyPlayed rp = new RecentlyPlayed(...);
dynamoDBMapper.save(rp); // Throws that error
recentlyPlayedRepository.save(rp); // Also throws the same error
I am using Spring v2.0.1.RELEASE. The wiki in the original docs warns about this error and describes what to do to mitigate. I did exactly what they said. But still no luck.
The link to that wiki is here - https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys
DynamoDB only supports primitive data types, it does not know how to convert your complex field (recentlyPlayedId) into a primitive, such as a String.
To show that this is the case, you can add the annotation #DynamoDBIgnore to your recentlyPlayedId attribute like this:
#DynamoDBIgnore
private RecentlyPlayedId recentlyPlayedId;
You also need to remove the #id annotation.
Your save function will then work, but the recentlyPlayedId will not be stored in the item. If you do want to save this field, you need to use the #DynamoDBTypeConverted annotation and write a converter class. The converter class defines how to convert the complex field into a String, and then uncovert the String into the complex field.
Removing getters/setters for the #Id field fixed the problem for me. This is suggested in https://github.com/derjust/spring-data-dynamodb/wiki/Use-Hash-Range-keys
not supported; requires #DynamoDBTyped or #DynamoDBTypeConverted",
i was getting this error when i defined model class with field JsonNode,i converted it to MAP<String,String>,now it is working fine

Design pattern for Filtering a custom datastructure

I have been given the below data structure and now I need to apply rules to filter the given cart. An example would be to filter out all items that are listed by user bob and with payment method credit card. The rule depends on case to case basis.
All these below are complex types in my request and response with concrete implementation without implementing an interface.
What will be the best design pattern to separate out my data structure and rules that are applied over it. Will Decorator pattern help? Your suggestions are welcome.
public class PaymentType {
private String paymentType;
}
public class Items {
private Integer itemId;
private String category;
private List<PaymentType> paymentOptions;
}
public class Group {
private Integer sellerId;
private List<Items> itemList;
}
public class Cart {
private Integer cardId;
private List<Group> group;
}
If for every PaymentType, you need to execute some different kind of operations , then you can try STATE PATTERN and delegate your request.
DECORATOR PATTERN is used to add extra responsibility during runtime, so I actually did not find that kind of scenario , may be I am missing somewhere some point.
Further Items , Group can be sub divided and there is a possibility of DECORATOR PATTERN.
If number of items are Fixed , then COMMAND PATTERN can be used , and UNDO scenario will even helpful for discard/accept item to/from CART

Categories

Resources