I'm new to Drools and decision tables. I need to create a rule to test if a Person is Older/young using the person age for the rule. The rule works but in infinite loop.
This is the rule, is basic, person age > 18 then the person is older, or, person age less than 18, person is young. The following is the HTML from my Excel file:
<style type="text/css">
table.tableizer-table {
font-size: 10px;
border: 1px solid #CCC;
font-family: Courier New, Courier, monospace;
}
.tableizer-table td {
padding: 4px;
margin: 3px;
border: 1px solid #CCC;
}
.tableizer-table th {
background-color: #DED11F;
color: #FFF;
font-weight: bold;
}
</style>
<table class="tableizer-table">
<thead><tr class="tableizer-firstrow"><th></th><th> </th><th>RuleTable Person</th><th> </th><th> </th><th> </th><th> </th></tr></thead><tbody>
<tr><td> </td><td> </td><td>CONDITION</td><td> </td><td>ACTION</td><td>ACTION</td><td>ACTION</td></tr>
<tr><td> </td><td> </td><td>p:Persona</td><td> </td><td> </td><td> </td><td> </td></tr>
<tr><td> </td><td> </td><td>edad >= </td><td>edad <</td><td>System.out.println( "Age: " + p.getEdad());</td><td>p.setMayorEdad($param);update(p);</td><td>System.out.println( "Older:" +p.isMayorEdad());</td></tr>
<tr><td> </td><td>Person rules</td><td>Status</td><td>Status</td><td>print</td><td>Is older?</td><td>Print ?</td></tr>
<tr><td> </td><td>Older</td><td>18</td><td> </td><td>X</td><td>true</td><td>X</td></tr>
<tr><td> </td><td>Yougn</td><td> </td><td>18</td><td>X</td><td>false</td><td>X</td></tr>
</tbody></table>
My Persona class is a simple POJO for test the decision table:
Person class (static, in main class):
public static class Persona{
String nombre;
String apellidoPaterno;
String apellidoMaterno;
int edad;
float salario;
boolean mayorEdad = false;
public Persona() {
super();
}
public Persona(String nombre, String apellidoPaterno, String apellidoMaterno, int edad, float salario) {
super();
this.nombre = nombre;
this.apellidoPaterno = apellidoPaterno;
this.apellidoMaterno = apellidoMaterno;
this.edad = edad;
this.salario = salario;
}
public String getNombre() {
return nombre;
}
public void setNombre(String nombre) {
this.nombre = nombre;
}
public String getApellidoPaterno() {
return apellidoPaterno;
}
public void setApellidoPaterno(String apellidoPaterno) {
this.apellidoPaterno = apellidoPaterno;
}
public String getApellidoMaterno() {
return apellidoMaterno;
}
public void setApellidoMaterno(String apellidoMaterno) {
this.apellidoMaterno = apellidoMaterno;
}
public int getEdad() {
return edad;
}
public void setEdad(int edad) {
this.edad = edad;
}
public float getSalario() {
return salario;
}
public void setSalario(float salario) {
this.salario = salario;
}
public boolean isMayorEdad() {
return mayorEdad;
}
public void setMayorEdad(boolean mayorEdad) {
this.mayorEdad = mayorEdad;
}
}
My main method, I'm using drools 6.5 with JRE 1.7:
public static final void main(String[] args) {
try {
// load up the knowledge base
KieServices ks = KieServices.Factory.get();
KieContainer kContainer = ks.getKieClasspathContainer();
KieSession kSession = kContainer.newKieSession("ksession-dtables");
Persona p = new Persona();
p.setNombre("Person");
p.setEdad(18);
p.setMayorEdad(true);
kSession.insert(p);
kSession.fireAllRules();
kSession.dispose();
} catch (Throwable t) {
t.printStackTrace();
}
}
this is the output, in infinite loop.
Age: 4
Older:false
Age: 4
Older:false
Age: 4
Older:false
Age: 4
Older:false
Age: 4
Thanks for any tip, link, tutorial, etc.
As soon as you use update()
on a fact, evaluation starts again, and the rule fires again, because the constraints are still true.
You could make mayorEdad a Boolean and add the constraint mayorEdad == null
.
Or you can avoid the update
if you don't expect other rules to fire based on the value of mayorEdad.