本文介绍了版本升级后例外的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在使用Optaplanner v7.11.0.Final的项目上存在分数持久性问题,我升级到了最新版本(v7.25.0.Final),但出现以下异常:

Having problem with Score persistance on a project using Optaplanner v7.11.0.Final, I upgraded to the latest one (v7.25.0.Final) but got the following exception :

The externalObject (Etat(super=DbObject(id=11), libelle=RCD, ordre=60)) with planningId ((class plr.domain.Etat$HibernateProxy$EZnO4cSz,11)) has no known workingObject (null).
Maybe the workingObject was never added because the planning solution doesn't have a @ProblemFactCollectionProperty annotation on a member with instances of the externalObject's class (class plr.domain.Etat$HibernateProxy$EZnO4cSz).

我终于发现升级到v7.17.0.Final时不会出现该异常.

I finally found that the exception does not appear when upgrading up to v7.17.0.Final.

自v7.18.0起完成了哪些工作,最终使代码失败了?

What have been done in since v7.18.0.Final that makes the code failing ?

如何解决?

有关更多信息,这是相对类

EDIT :For more information, here are the relative classes

package org.optaplanner.plr.domain;

import javax.persistence.Column;
import javax.persistence.Entity;

import org.optaplanner.core.api.domain.lookup.PlanningId;

import lombok.Data;
import lombok.EqualsAndHashCode;
import lombok.ToString;

@Data
@ToString(callSuper = true)
@EqualsAndHashCode(callSuper = true)
@Entity
public class Etat extends DbObject {

    @Column
    private String libelle;

    @Column
    private int ordre;

    @Override
    @PlanningId
    public Integer getId() {
        return super.getId();
    }
}

及其超类

package org.optaplanner.plr.domain;

import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.MappedSuperclass;

import lombok.Data;
import lombok.EqualsAndHashCode;

@MappedSuperclass
@Data
@EqualsAndHashCode
public abstract class DbObject {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Integer id;
}

最后,这是有史以来最简单的配置:)

and finally, the simplest config ever :)

<?xml version="1.0" encoding="UTF-8"?>
<solver>
    <!-- To solve faster by saturating multiple CPU cores -->
    <moveThreadCount>4</moveThreadCount>
    <solutionClass>org.optaplanner.plr.domain.PlannifSolution</solutionClass>
    <entityClass>org.optaplanner.plr.domain.Plannif</entityClass>
    <scoreDirectorFactory>
        <scoreDrl>org/optaplanner/plr/solver/score.drl</scoreDrl>
        <initializingScoreTrend>ONLY_DOWN</initializingScoreTrend>
    </scoreDirectorFactory>
    <termination>
        <secondsSpentLimit>1200</secondsSpentLimit>
        <unimprovedSecondsSpentLimit>300</unimprovedSecondsSpentLimit>
    </termination>
</solver>

整个踪迹是

java.lang.IllegalStateException: Failed to execute CommandLineRunner
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:782)
    at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:763)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:318)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1213)
    at org.springframework.boot.SpringApplication.run(SpringApplication.java:1202)
    at org.optaplanner.plr.Application.main(Application.java:64)
Caused by: java.lang.IllegalStateException: The move thread with moveThreadIndex (2) has thrown an exception. Relayed here in the parent thread.
    at org.optaplanner.core.impl.heuristic.thread.OrderByMoveIndexBlockingQueue.take(OrderByMoveIndexBlockingQueue.java:142)
    at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.forageResult(MultiThreadedLocalSearchDecider.java:187)
    at org.optaplanner.core.impl.localsearch.decider.MultiThreadedLocalSearchDecider.decideNextStep(MultiThreadedLocalSearchDecider.java:157)
    at org.optaplanner.core.impl.localsearch.DefaultLocalSearchPhase.solve(DefaultLocalSearchPhase.java:70)
    at org.optaplanner.core.impl.solver.AbstractSolver.runPhases(AbstractSolver.java:88)
    at org.optaplanner.core.impl.solver.DefaultSolver.solve(DefaultSolver.java:191)
    at org.optaplanner.plr.Application$1.run(Application.java:222)
    at org.optaplanner.plr.Application$1$$FastClassBySpringCGLIB$$7557a0d1.invoke(<generated>)
    at org.springframework.cglib.proxy.MethodProxy.invoke(MethodProxy.java:218)
    at org.springframework.aop.framework.CglibAopProxy$CglibMethodInvocation.invokeJoinpoint(CglibAopProxy.java:749)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:163)
    at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:295)
    at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
    at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)
    at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688)
    at org.optaplanner.plr.Application$1$$EnhancerBySpringCGLIB$$c098b4dc.run(<generated>)
    at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:779)
    ... 5 common frames omitted
Caused by: java.lang.IllegalStateException: The externalObject (Etat(super=DbObject(id=11), libelle=RCD, ordre=60)) with planningId ((class org.optaplanner.plr.domain.Etat$HibernateProxy$YghGFDSA,11)) has no known workingObject (null).
Maybe the workingObject was never added because the planning solution doesn't have a @ProblemFactCollectionProperty annotation on a member with instances of the externalObject's class (class org.optaplanner.plr.domain.Etat$HibernateProxy$YghGFDSA).
    at org.optaplanner.core.impl.domain.lookup.PlanningIdLookUpStrategy.lookUpWorkingObject(PlanningIdLookUpStrategy.java:66)
    at org.optaplanner.core.impl.domain.lookup.LookUpManager.lookUpWorkingObject(LookUpManager.java:75)
    at org.optaplanner.core.impl.score.director.AbstractScoreDirector.lookUpWorkingObject(AbstractScoreDirector.java:509)
    at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:85)
    at org.optaplanner.core.impl.heuristic.selector.move.generic.ChangeMove.rebase(ChangeMove.java:33)
    at org.optaplanner.core.impl.heuristic.thread.MoveThreadRunner.run(MoveThreadRunner.java:139)
    at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
    at java.lang.Thread.run(Thread.java:748)

推荐答案

感谢 Geoffrey answer yurloc 注释,我终于找到了问题所在.

Thanks to Geoffrey answer and yurloc comments, I finally found what was the problem.

首先,Etat个对象通过与另一个对象的联接而来.将ManyToOne提取类型更改为Eager而不是Lazy表明,我遇到了相同的异常,但是使用了Etat对象而不是其Hibernate代理.

First, Etat objects were coming through a join with another object. Changing the ManyToOne fetch type to Eager instead of Lazy showed that I got the same exception but with Etat objects instead of their Hibernate proxies.

因此,这意味着Optaplanner无法识别这些对象.确实,我在Etat的每个计划变量中使用了特定范围,但从未在问题事实中加载所有这些变量.

So it means that these objects were not know by Optaplanner. Indeed, I was using a specific range per planning variable for Etat but never load all these ones in the problem facts.

最后,它与分离对象与附加对象无关,并且可以将联接获取类型放回Lazy值.

In the end, it has nothing to do with detached vs attached objects and the join fetch type can be put back to Lazy value.

这篇关于版本升级后例外的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-28 15:17