我们一直在改进OptaPlanner与JEE其余部分的集成,因此,构建可以正常工作的最终用户应用程序更加容易。 让我们看一下改进的JPA Hibernate集成。
基础
JPA Hibernate和OptaPlanner都可以在POJO(普通的旧Java对象)上工作,因此只需在域对象上添加一些JPA批注以使其与JPA Hibernate保持一致,并添加一些OptaPlanner批注即可解决OptaPlanner的优化问题。
在每个问题事实类上,通常只有JPA批注:
@Entity // JPA annotation
public class Computer {private int cpuPower;private int memory;private int networkBandwidth;private int cost;...
}
在每个计划实体类上,都有JPA和OptaPlanner批注:
@PlanningEntity // OptaPlanner annotation
@Entity // JPA annotation
public class Process {private int requiredCpuPower;private int requiredMemory;private int requiredNetworkBandwidth;@PlanningVariable(...) // OptaPlanner annotation@ManyToOne() // JPA annotationprivate Computer computer;...
}
不要将JPA实体(任何持久存储在数据库中的对象)与OptaPlanner规划实体(在解决过程中由OptaPlanner更改的对象)混淆。
坚持得分
默认情况下,JPA Hibernate将通过Java序列化将Score
放在BLOB
列中。 这是不希望的,因为它阻止了在JPA-QL查询中使用分数。 此外,在升级OptaPlanner版本时,它还会触发数据库问题。
因此,OptaPlanner 6.4.0.Beta1
具有一个新的jar optaplanner-persistence-jpa
,其中包含每种评分类型的Hibernate类型。 像这样使用它:
@PlanningSolution // OptaPlanner annotation
@Entity // JPA annotation
@TypeDef(defaultForType = HardSoftScore.class, typeClass = HardSoftScoreHibernateType.class) // Hibernate annotation
public class CloudBalance implements Solution<HardSoftScore> {@Columns(columns = {@Column(name = "hardScore"), @Column(name = "softScore")}) // JPA annotationprivate HardSoftScore score;...
}
这会将HardSoftScore
放入2个INTEGER
列,而不是BLOB
列。 OptaPlanner参考手册包含有关如何正确处理BigDecimal
和/或可弯曲分数的更多信息。
克隆陷阱
在JPA模型中,问题事实通常引用计划解决方案,这可能会破坏计划克隆(如果使用默认计划克隆器)。
为了克服这个问题,只需使用@DeepPlanningClone
注释注释引用计划解决方案或计划实体的问题事实类:
@DeepPlanningClone // OptaPlanner annotation: Force the default planning cloner to planning clone this class too
@Entity // JPA annotation
public class Computer {@ManyToOneprivate CloudBalance cloudBalance;...
}
这样, Computer
类也正在计划克隆,并且克隆的cloudBalance
字段将指向CloudBalance
克隆。
结论
您可以对JPA Hibernate和OptaPlanner使用相同的域类,无需重复您的域!
翻译自: https://www.javacodegeeks.com/2015/09/integrating-jpa-hibernate-with-optaplanner.html