我正在执行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对象传递给我的名册时...
在调用RosterController
之前,在solverManager.solve(...)
中放置一个断点。您会看到Roster
实例的shiftList
字段为null
。