当简单的JSON对象传递给控制器 时,Optaplanner solutionClassentityCollectionProperty永远不应该返回null错误

问题描述 投票:0回答:1

我正在执行optaplanner-spring-boot-starter云平衡项目,我正在尝试根据员工的技能水平分配轮班。但是,当我将JSON对象传递给我的名册控制器时,出现一条错误消息:

java.lang.IllegalArgumentException:solutionClass(com.redhat.optaplannersbs.domain.Roster类)的entityCollectionProperty(com.redhat.optaplannersbs.domain.Roster类上的bean属性shiftList)应该永远不会返回null。

我不明白问题是什么,因为我基本上正在做与云平衡问题相同的事情,并且可以正常运行并解决。

这是我的员工班级代码:

public class Employee {
    private int eid;

    private String name;

    private int skillLevel;

    public Employee(){

    }

    public int getEid() {
        return eid;
    }

    public void setEid(int eid) {
        this.eid = eid;
    }

    public String getName() {
        return name;
    }

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

    // constraint getters and setters
    public int getSkillLevel() {
        return skillLevel;
    }

    public void setSkillLevel(int skillLevel) {
        this.skillLevel = skillLevel;
    }


}

这是我班次的代码:

 @PlanningEntity
public class Shift {
    private int sid;

    private LocalTime startTime;

    private LocalTime endTime;

    private int requiredSkillLevel;

    @PlanningVariable(valueRangeProviderRefs = "employee")
    private Employee employee;

    public Shift(){

    }

    public Shift(Long deptId, Long spotId, LocalTime startTime,
                 LocalTime endTime, Long employeeId){
        this.startTime = startTime;
        this.endTime = endTime;
    }

    public int getSid() {
        return sid;
    }

    public void setSid(int sid) {
        this.sid = sid;
    }

    public LocalTime getStartTime() {
        return startTime;
    }

    public void setStartTime(LocalTime startTime) {
        this.startTime = startTime;
    }

    public LocalTime getEndTime() {
        return endTime;
    }

    public void setEndTime(LocalTime endTime) {
        this.endTime = endTime;
    }


    // planning variable getter and setter

    public Employee getEmployee() {
        return employee;
    }

    public void setEmployee(Employee employee) {
        this.employee = employee;
    }

    public int getRequiredSkillLevel() {
        return requiredSkillLevel;
    }

    public void setRequiredSkillLevel(int requiredSkillLevel) {
        this.requiredSkillLevel = requiredSkillLevel;
    }
}

这是我的花名册课程:

 @PlanningSolution
public class Roster {

    private List<Employee> employeeList;

    private List<Shift> shiftList;

    private HardSoftScore score;

    public Roster(List<Employee> employeeList, List<Shift> shiftList) {
        this.employeeList = employeeList;
        this.shiftList = shiftList;
    }

    @ProblemFactCollectionProperty
    @ValueRangeProvider(id="employee")
    public List<Employee> getEmployeeList() {
        return employeeList;
    }

    public void setEmployeeList(List<Employee> employeeList) {
        this.employeeList = employeeList;
    }

    @PlanningEntityCollectionProperty
    public List<Shift> getShiftList() {
        return shiftList;
    }

    public void setShiftList(List<Shift> shiftList) {
        this.shiftList = shiftList;
    }

    @PlanningScore
    public HardSoftScore getScore() {
        return score;
    }

    public void setScore(HardSoftScore score) {
        this.score = score;
    }
}

这里是我的约束提供者:

    public class ConstraintProvider implements org.optaplanner.core.api.score.stream.ConstraintProvider {
    @Override
    public Constraint[] defineConstraints(ConstraintFactory constraintFactory) {
        return new Constraint[]{
                requiredSkillLevelOfEmployeesForShifts(constraintFactory)
        };
    }

    private Constraint requiredSkillLevelOfEmployeesForShifts(ConstraintFactory constraintFactory) {
        return constraintFactory.from(Shift.class)
                .groupBy(Shift::getEmployee, sum(Shift::getRequiredSkillLevel))
                .filter((employee, requiredSkillLevel) -> requiredSkillLevel > employee.getSkillLevel())
                .penalize("requiredSkillLevelForShifts",
                HardSoftScore.ONE_HARD,
                (employee, requiredSkillLevel) -> requiredSkillLevel - employee.getSkillLevel());
    }
}

这里是我的控制器:

@RestController
@RequestMapping("/roster")
public class RosterController {

    @Autowired
    private SolverManager<Roster, UUID> solverManager;

    @PostMapping("/solve")
    public Roster solve(@RequestBody Roster problem) {
        UUID problemId = UUID.randomUUID();
        // Submit the problem to start solving
        SolverJob<Roster, UUID> solverJob = solverManager.solve(problemId, problem);
        Roster solution;
        try {
            // Wait until the solving ends
            solution = solverJob.getFinalBestSolution();
        } catch (InterruptedException | ExecutionException e) {
            throw new IllegalStateException("Solving failed.", e);
        }
        return solution;
    }

}

我通过发布请求传递的JSON数据如下:

 {
   "shifts":[
      {
         "sid":0,
         "startTime":"09:00",
         "endTime":"18:00",
         "requiredSkillLevel": 12
      },
      {
         "sid":1,
         "startTime":"12:00",
         "endTime":"20:00",
         "requiredSkillLevel": 10
      },
      {
         "sid":2,
         "startTime":"18:00",
         "endTime":"00:00",
         "requiredSkillLevel": 10
      },
      {
         "sid": 3,
         "startTime":"09:00",
         "endTime":"18:00",
         "requiredSkillLevel": 12
      },
      {
         "sid":4,
         "startTime":"12:00",
         "endTime":"20:00",
         "requiredSkillLevel": 10
      },
      {
         "sid":5,
         "startTime":"18:00",
         "endTime":"00:00",
         "requiredSkillLevel":10
      },
      {
         "sid":6,
         "startTime":"09:00",
         "endTime":"18:00",
         "requiredSkillLevel": 12
      },
      {
         "sid":7,
         "startTime":"12:00",
         "endTime":"20:00",
         "requiredSkillLevel": 10
      },
      {
         "sid":8,
         "startTime":"18:00",
         "endTime":"00:00",
         "requiredSkillLevel":10
      },
      {
         "sid":9,
         "startTime":"09:00",
         "endTime":"18:00",
         "requiredSkillLevel": 12
      },
      {
         "sid":10,
         "startTime":"12:00",
         "endTime":"20:00",
         "requiredSkillLevel": 10
      },
      {
         "sid":11,
         "startTime":"18:00",
         "endTime":"00:00",
         "requiredSkillLevel":10
      },
      {
         "sid":12,
         "startTime":"09:00",
         "endTime":"18:00",
         "requiredSkillLevel": 12
      },
      {
         "sid":13,
         "startTime":"12:00",
         "endTime":"20:00",
         "requiredSkillLevel": 10
      },
      {
         "sid":14,
         "startTime":"18:00",
         "endTime":"00:00",
         "requiredSkillLevel":10
      }
   ],
   "employees":[
      {
         "eid":0,
         "name":"john",
         "skillLevel": 10
      },
      {
         "eid":1,
         "name":"elaine",
         "skillLevel": 2
      },
      {
         "eid":2,
         "name":"kieran",
         "skillLevel": 11
      },
      {
         "eid":3,
         "name":"maeve",
         "skillLevel": 10
      },
      {
         "eid":4,
         "name":"steve",
         "skillLevel": 9
      },
      {
         "eid":5,
         "name":"steve",
         "skillLevel": 9
      },
      {
         "eid":6,
         "name":"steve",
         "skillLevel": 15
      },
      {
         "eid":7,
         "name":"amy",
         "skillLevel": 11
      }
   ]
}

[如果我正在弄一个更简单的云平衡应用程序版本,如果有人可以弄清楚我哪里出了错,那将是很大的帮助,我应该不会收到此错误,]

我正在执行optaplanner-spring-boot-starter云平衡项目,我正在尝试根据员工的技能水平分配轮班。但是,当我将JSON对象传递给我的名册时...

java spring-boot optaplanner
1个回答
0
投票

在调用RosterController之前,在solverManager.solve(...)中放置一个断点。您会看到Roster实例的shiftList字段为null

© www.soinside.com 2019 - 2024. All rights reserved.