Need to add multiple items in list - decision table - Drools

那年仲夏 提交于 2021-02-13 17:35:40

问题


I need to create a new multiple instance of objects for the Pojo class in drools decision table. I have implemented using two facts Student fact and subject fact class. I need to fire all the rules in the decision table and I need to add all the values into array-list of the objects. But I'm getting only last rule values of decision table. It seems like decision table values are getting overridden.

Fact 1

Class StudentFact{

 private int id;
 private String name;
 private List<SubejctFact> subjectList;

 public void setId(int id){
    this.id = id;
 }

 public int getId(){
    return id;
 } 

 public void setName(String name){
    this.Name = name;
 }    

 public String getName(){
    return name;
 }

     public void setSubjectList(List<Subject> subjectList) {
        this.subjectList = subjectList;
    }



    public int getSubjectList() {
        return subjectList;
    }




}

Fact 2

Class SubjectFact{
 private int subId;
 private String subjectName;

 public void setSubId(int subId){
     this.subId= subId;
 }

 public int getSubId(){
   return subId;
 }

 public void setSubjectName(String subjectName){
      this.subjectName = subjectName;
 }

 public int getSubejctName(){
      return subjectName;
 }

}

Current Response

{
  "id":123,
  "name": "xyz",
  "subjectList": [
     { 
        "id": 6,
        "name":"Hindi"
     },
     {
        "id": 6,
        "name":"Hindi"
     }
}

Expected Response

 {
      "id":123,
      "name": "xyz",
      "subjectList": [
         { 
            "id": 5,
            "name":"English"
         },
         {
            "id": 6,
            "name":"Hindi"
         }
    }

My Decision Table looks like

Any one pls advise to achieve the expected response?


回答1:


Each row in a table becomes a rule, each action column becomes a row in then block.
For each rule you need a statement to create Subject, statements to populate it and statement to add it to matching student.
Values in 'CREATE' and 'COLLECT' are needed, otherwise action will be skipped.
; is required in a cell without 'target object' and it is not required when you provide '$subject' and '$student' objects. Don't ask me why. Just analyzed generated drl.
You may want to hide two 'technical rows'.

This will generate two rules like below

package draft;
//generated from Decision Table
import draft.Student;
import draft.Subject;
// rule values at A9, header at A4
rule "Rule 1"
    when
        $student:Student(id == "123")
    then
        Subject $subject = new Subject();
        $subject.setSubId(5);
        $subject.setSubjectName('English');
        $student.addSubject($subject);
end

// rule values at A10, header at A4
rule "Rule 2"
    when
        $student:Student(id == "123")
    then
        Subject $subject = new Subject();
        $subject.setSubId(6);
        $subject.setSubjectName('Hindi');
        $student.addSubject($subject);
end

PS: I was struggling with " being automatically replaced by Calc editor to `` which was not valid symbol for drools parser, so I used single quotes, which appeared to be special symbol on the start of the cell in the editor and skipped. So actual cell value which finally worked for me was ''English'.

Here are my models

public class Student {
    private int id;
    private String name;
    private List<Subject> subjectList = new ArrayList<>();

    public Student(int id, String name) {
        this.id = id;
        this.name = name;
    }

    public void setId(int id) {
        this.id = id;
    }

    public int getId() {
        return id;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getName() {
        return name;
    }

    public void addSubject(Subject subject) {
        subjectList.add(subject);
    }

    public void setSubjectList(List<Subject> subjectList) {
        this.subjectList = subjectList;
    }

    public List<Subject> getSubjectList() {
        return subjectList;
    }
}

public class Subject {
    private int subId;
    private String subjectName;

    public void setSubId(int subId) {
        this.subId = subId;
    }

    public int getSubId() {
        return subId;
    }

    public void setSubjectName(String subjectName) {
        this.subjectName = subjectName;
    }

    public String getSubejctName() {
        return subjectName;
    }
}

test

@DroolsSession(resources = "draft/ApplicableSubjects.xls",
        builderProperties = "drools.dump.dir = target/dump")
public class PlaygroundTest {

    @Rule
    public DroolsAssert drools = new DroolsAssert();

    @Test
    public void testIt() {
        drools.insertAndFire(new Student(123, "Student 123"));
        drools.printFacts();
    }
}

test output

00:00:00 --> inserted: Student[id=123,name=Student 123,subjectList=[]]
00:00:00 --> fireAllRules
00:00:00 <-- 'Rule 1' has been activated by the tuple [Student]
00:00:00 <-- 'Rule 2' has been activated by the tuple [Student]
00:00:00 Facts (1):
Student[id=123,name=Student 123,subjectList=[draft.Subject@1ded7b14, draft.Subject@29be7749]]


来源:https://stackoverflow.com/questions/62097561/need-to-add-multiple-items-in-list-decision-table-drools

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!