Spring Data无法使用* ScoreHibernateType保留OptaPlanner的Score对象

时间:2018-10-03 08:27:55

标签: hibernate spring-boot jpa spring-data-jpa optaplanner

我想使用Spring-boot-data将OptaPlanner的域对象持久保存在数据库中,并且根据指南,我已经完成了休眠映射任务,除Score对象外,其他一切看起来都很好。

如果没有任何特殊配置,得分对象可以作为BLOB列保存在DB中,但是如果基于指南(17.2.1.1。JPA和Hibernate:坚持得分),它总是会引发如下异常: >

java.lang.AbstractMethodError: org.optaplanner.persistence.jpa.impl.score.buildin.hardmediumsoft.HardMediumSoftScoreHibernateType.replace(Ljava/lang/Object;Ljava/lang/Object;Lorg/hibernate/engine/spi/SharedSessionContractImplementor;Ljava/lang/Object;)Ljava/lang/Object;
at org.hibernate.type.CompositeCustomType.replace(CompositeCustomType.java:178)
at org.hibernate.type.AbstractType.replace(AbstractType.java:144)
at org.hibernate.type.TypeHelper.replace(TypeHelper.java:194)
at org.hibernate.event.internal.DefaultMergeEventListener.copyValues(DefaultMergeEventListener.java:431)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsTransient(DefaultMergeEventListener.java:233)
at org.hibernate.event.internal.DefaultMergeEventListener.entityIsDetached(DefaultMergeEventListener.java:301)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:170)
at org.hibernate.event.internal.DefaultMergeEventListener.onMerge(DefaultMergeEventListener.java:69)
at org.hibernate.internal.SessionImpl.fireMerge(SessionImpl.java:884)
at org.hibernate.internal.SessionImpl.merge(SessionImpl.java:870)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.orm.jpa.SharedEntityManagerCreator$SharedEntityManagerInvocationHandler.invoke(SharedEntityManagerCreator.java:305)
at com.sun.proxy.$Proxy86.merge(Unknown Source)
at org.springframework.data.jpa.repository.support.SimpleJpaRepository.save(SimpleJpaRepository.java:493)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.springframework.data.repository.core.support.RepositoryComposition$RepositoryFragments.invoke(RepositoryComposition.java:377)
at org.springframework.data.repository.core.support.RepositoryComposition.invoke(RepositoryComposition.java:200)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$ImplementationMethodExecutionInterceptor.invoke(RepositoryFactorySupport.java:641)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:605)
at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:590)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:59)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:294)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:98)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:139)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.jpa.repository.support.CrudMethodMetadataPostProcessor$CrudMethodMetadataPopulatingMethodInterceptor.invoke(CrudMethodMetadataPostProcessor.java:135)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.data.repository.core.support.SurroundingTransactionDetectorMethodInterceptor.invoke(SurroundingTransactionDetectorMethodInterceptor.java:61)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:185)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:212)
at com.sun.proxy.$Proxy93.save(Unknown Source)
at cc.tonny.optaplanner.exercise.springbootcloudbalance.CommandLineAppStartupRunner.run(CommandLineAppStartupRunner.java:64)
at org.springframework.boot.SpringApplication.callRunner(SpringApplication.java:818)
at org.springframework.boot.SpringApplication.callRunners(SpringApplication.java:802)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:341)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1277)
at org.springframework.boot.SpringApplication.run(SpringApplication.java:1265)
at cc.tonny.optaplanner.exercise.springbootcloudbalance.SpringbootCloudbalanceApplication.main(SpringbootCloudbalanceApplication.java:10)

请检查https://github.com/tonny1983/springboot-cloudbalance上的代码

2 个答案:

答案 0 :(得分:1)

最后,我将它与spring-boot-jpa v5.2.x一起在hibernate v2.x中工作,我将按如下说明修补程序:

  1. 创建一个扩展org.optaplanner.persistence.jpa.impl.score.AbstractScoreHibernateType的新类并实现org.hibernate.usertype.CompositeUserType中定义的所有方法(您可以从AbstractScoreHibernateType复制所有代码,而只需从{{1}更改参数的类型}到org.hibernate.engine.spi.SessionImplementor
  2. 创建一个新的org.hibernate.engine.spi.SharedSessionContractImplementor类,以扩展在步骤1中创建的类,并像原始*SoftScoreHibernateType类一样添加其构造方法
  3. 在我的情况下,*SoftScoreHibernateType方法抛出getPropertyValue,因为java.lang.ArrayIndexOutOfBoundsException数组仅包含三个项目-硬分,中分和软分,但是{{1} }是1到3。因此,我覆盖了该方法,只是将最后一行更改为levelNumbers propertyIndex return levelNumbers[propertyIndex

    仅此而已。

答案 1 :(得分:0)

使用支持Hibernate 5.3+的OptaPlanner 7.18.0.Final或更高版本