Spring 数据 Neo4j - 参数类型不匹配

Spring Data Neo4j - Argument Type Mismatch

我使用了 Neo4j 3.0.6、neo4j-ogm 2.0.5、Spring boot starter 1.4.1 RELEASE、Lucene 5.5.2

这是我的Machine和machineSectionSummaryclass(我只有post这个字段,其实还有属性和构造函数)。当我调用 updateMachineSectionSummary 函数时,调用此函数并重新启动程序后,我无法调用 machineRepository.findByName 并得到以下错误。我怎样才能解决这个问题?我已经尝试删除日期,更改关系名称,但它不起作用

@NodeEntity
public class Machine {
@GraphId
Long graphId;
String id;
private String name;
private String field;
private Date startDate;
private Date endDate;
@Relationship(type = "HAS_DEPTH_UNIT", direction = "OUTGOING")
private Unit depthUnit;
private Double duration;
@Relationship(type = "HAS_DURATION_UNIT", direction = "OUTGOING")
private Unit durationUnit;
private Double cost;
@Relationship(type = "HAS_CURRENCY", direction = "OUTGOING")
private Currency currency;
private Double exchangeRate;
@Transient
private Boolean maxCost;
}

@NodeEntity
public class MachineSectionSummary {
@GraphId
Long graphId;
String id;
@Relationship(type = "HAS_MACHINE", direction = "OUTGOING")
private Machine machine;
private String sectionGroup;
private String category;
private Double duration;
private Double percentDuration;
private Double cost;
private Double percentCost;
@Relationship(type = "HAS_CURRENCY", direction = "OUTGOING")
private Currency currency;  

}

在这个函数中,当我尝试 findById 时,它首先在 运行 上正常工作(在清除数据库和 运行 程序之后),但是在我停止并重新 运行 程序,老是报错

public void updateMachineSectionSummary(String id) {
    Machine currentMachine = findById(id);
    if (currentMachine == null) {
        return;
    }
    Engine currentEngine = engineService.findByMachineIdAndName(currentMachine.getId(), "Value");
    if (currentEngine == null) {
        return;
    }
    List<LineItem> currentLineItemList = lineItemService.findByEngineIdAndActivityTypeOrderByNoAsc(currentEngine.getId(), "Inside");


    List<String> sectionGroupList = new ArrayList<String>();
    sectionGroupList.add("Section 1");
    sectionGroupList.add("Section 2");
    sectionGroupList.add("Section 3");
    sectionGroupList.add("Section 4");
    for (String sectionGroup : sectionGroupList) {
        Double durationTotal = currentLineItemList.stream().filter(d -> d.getSection().getGroup().equalsIgnoreCase(sectionGroup))
                .mapToDouble(LineItem::getDuration).sum();
        durationTotal = durationTotal / 24;
        Double percentDurationTotal = (durationTotal / durationTotal) * 100.0;

        MachineSectionSummary currentWSSTotal = machineSectionSummaryService.findByMachineNameAndSectionGroupAndCategory(currentMachine.getName(),
                sectionGroup, "Total");
        if (currentWSSTotal != null) {
            currentWSSTotal.setDuration(durationTotal);
            currentWSSTotal.setPercentDuration(percentDurationTotal);
            machineSectionSummaryService.save(currentWSSTotal);
        }
    }
}

这是我运行程序(第二次)

时的日志错误
java.lang.IllegalArgumentException: argument type mismatch
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66]
 at org.neo4j.ogm.entity.io.MethodWriter.write(MethodWriter.java:40) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.entity.io.MethodWriter.write(MethodWriter.java:70) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.context.GraphEntityMapper.writeProperty(GraphEntityMapper.java:234) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.context.GraphEntityMapper.setProperties(GraphEntityMapper.java:186) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.context.GraphEntityMapper.mapNodes(GraphEntityMapper.java:162) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.context.GraphEntityMapper.mapEntities(GraphEntityMapper.java:145) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.context.GraphEntityMapper.map(GraphEntityMapper.java:120) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.context.GraphRowListModelMapper.map(GraphRowListModelMapper.java:56) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.session.delegates.LoadByTypeDelegate.loadAll(LoadByTypeDelegate.java:94) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.session.delegates.LoadByTypeDelegate.loadAll(LoadByTypeDelegate.java:157) ~[neo4j-ogm-core-2.0.5.jar:na]
 at org.neo4j.ogm.session.Neo4jSession.loadAll(Neo4jSession.java:226) ~[neo4j-ogm-core-2.0.5.jar:na]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66]
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:133) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:121) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at com.sun.proxy.$Proxy77.loadAll(Unknown Source) ~[na:na]
 at org.springframework.data.neo4j.repository.query.derived.DerivedGraphRepositoryQuery.execute(DerivedGraphRepositoryQuery.java:65) ~[spring-data-neo4j-4.1.3.RELEASE.jar:na]
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.doInvoke(RepositoryFactorySupport.java:482) ~[spring-data-commons-1.12.3.RELEASE.jar:na]
 at org.springframework.data.repository.core.support.RepositoryFactorySupport$QueryExecutorMethodInterceptor.invoke(RepositoryFactorySupport.java:460) ~[spring-data-commons-1.12.3.RELEASE.jar:na]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.data.projection.DefaultMethodInvokingMethodInterceptor.invoke(DefaultMethodInvokingMethodInterceptor.java:61) ~[spring-data-commons-1.12.3.RELEASE.jar:na]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:136) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.interceptor.ExposeInvocationInterceptor.invoke(ExposeInvocationInterceptor.java:92) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at com.sun.proxy.$Proxy116.findByName(Unknown Source) ~[na:na]
 at com.test.wp.service.MachineServiceImpl.findByName(MachineServiceImpl.java:58) ~[classes/:na]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66]
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.transaction.interceptor.TransactionInterceptor.proceedWithInvocation(TransactionInterceptor.java:99) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:281) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) ~[spring-tx-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at com.sun.proxy.$Proxy121.findByName(Unknown Source) ~[na:na]
 at com.test.wp.service.InitializationServiceImpl.initGlobalOffsetMachines(InitializationServiceImpl.java:998) ~[classes/:na]
 at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) ~[na:1.8.0_66]
 at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) ~[na:1.8.0_66]
 at java.lang.reflect.Method.invoke(Unknown Source) ~[na:1.8.0_66]
 at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) ~[spring-aop-4.3.3.RELEASE.jar:4.3.3.RELEASE]
 at..

更新

我在 Github 创建了 sampleProject。希望这个示例有帮助。谢谢

这有两部分:第一部分涉及您的代码,第二部分是 OGM 在遇到这种情况时应该做什么。

MachineSectionSummary 有一个名为 Double percentDuration 的字段。当您初始化数据库时,它会将每个实例设置为 0.0。你第一次 运行 /initMachineSectionSummary 它调用 updateMachineSectionSummary()

引入问题的行在这里:Double percentDurationTotal = (durationTotal / durationTotal) * 100.0;。创建 durationTotal 的表达式总是 returns 0.0。此计算将导致 NaN,然后我们将其设置为 MachineSectionSummary.percentDuration。 OGM 然后将此值保存到 Neo4j。当您尝试从数据库中检索 NaN 值并将其映射回 MachineSectionSummary 时,就会出现问题。此时的 OGM 期待一个 Double 但得到一个名为 "NaN" 的字符串,它爆炸了异常:java.lang.IllegalArgumentException: argument type mismatch.

过去我从事过很多数值项目,我的建议是防止 NaN 出现;那就是在它可能起源的地方做一些防御性编码。这应该可以解决您的主要问题。

这里介绍第二个问题:我们期望OGM在这里做什么?在某些情况下,某些用户可能希望将 NaN 存储在数据库中。某些用户可能希望确保 NaN 始终为 null。无论哪种方式,OGM 都应该用更好的错误消息提醒开发人员。