Мы улучшаем интеграцию OptaPlanner с остальной частью JEE, поэтому проще создавать приложения для конечных пользователей, которые просто работают. Давайте посмотрим на улучшенную интеграцию JPA Hibernate.
Основы
Как JPA Hibernate, так и OptaPlanner работают с POJO (Plain Old Java Objects), поэтому просто добавьте несколько аннотаций JPA к объектам вашего домена, чтобы сохранить их в JPA Hibernate, и добавьте некоторые аннотации OptaPlanner, чтобы решить вашу проблему оптимизации с OptaPlanner.
Для каждого класса фактов проблемы обычно есть только аннотации JPA:
01
02
03
04
05
06
07
08
09
10
|
@Entity // JPA annotation public class Computer { private int cpuPower; private int memory; private int networkBandwidth; private int cost; ... } |
Для каждого класса объекта планирования имеются аннотации JPA и OptaPlanner:
01
02
03
04
05
06
07
08
09
10
11
12
13
14
|
@PlanningEntity // OptaPlanner annotation @Entity // JPA annotation public class Process { private int requiredCpuPower; private int requiredMemory; private int requiredNetworkBandwidth; @PlanningVariable (...) // OptaPlanner annotation @ManyToOne () // JPA annotation private Computer computer; ... } |
Не путайте объект JPA (любой объект, который сохраняется в базе данных) с объектом планирования OptaPlanner (объект, который изменяется в ходе решения OptaPlanner).
Сохраняя счет
По умолчанию JPA Hibernate помещает Score
в столбец BLOB
посредством сериализации Java. Это нежелательно, поскольку мешает использовать оценку в запросе JPA-QL. Кроме того, он вызывает проблемы с базой данных при обновлении версии OptaPlanner.
Поэтому в OptaPlanner 6.4.0.Beta1
есть новый jar optaplanner-persistence-jpa
который содержит тип Hibernate для каждого типа оценки. Используйте это так:
01
02
03
04
05
06
07
08
09
10
|
@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 annotation private HardSoftScore score; ... } |
Это помещает HardSoftScore
в 2 столбца INTEGER
вместо столбца BLOB
. Справочное руководство OptaPlanner содержит больше информации о том, как правильно обращаться с BigDecimal
и / или сгибаемыми партитурами.
Ловушка клонирования
В модели JPA распространено, что факты проблемы ссылаются на решение планирования, которое может повредить клонирование планирования (если используется клонер планирования по умолчанию).
Чтобы преодолеть это, просто аннотируйте классы фактов проблемы, которые ссылаются на решение планирования или объект планирования, с помощью аннотации @DeepPlanningClone
:
1
2
3
4
5
6
7
8
9
|
@DeepPlanningClone // OptaPlanner annotation: Force the default planning cloner to planning clone this class too @Entity // JPA annotation public class Computer { @ManyToOne private CloudBalance cloudBalance; ... } |
Таким образом, класс Computer
планирует клонирование, и поле клона cloudBalance
будет указывать на клон CloudBalance
.
Вывод
Вы можете использовать те же классы домена для JPA Hibernate и OptaPlanner, нет необходимости дублировать ваш домен!
Ссылка: | Интеграция JPA Hibernate с OptaPlanner от нашего партнера JCG Джеффри Де Смета в блоге OptaPlanner . |