Spring Data Neo4j - Argument Type Mismatch

北城余情 提交于 2020-01-04 05:41:13

问题


I used Neo4j 3.0.6, neo4j-ogm 2.0.5, Spring boot starter 1.4.1 RELEASE, Lucene 5.5.2

This is my Machine and machineSectionSummary class (I only post the field, actually there are properties and constructors). When I call updateMachineSectionSummary function, after call this function and relaunch the program, I can't call machineRepository.findByName and get the error below. How can I fix this? I already tried to remove the Date, changing the relationship name, but its not working

@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;  

}

In this function, when I try to findById, its work properly on first Run (after clear database and run the program), but after I stop and re-run the program, it always error.

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);
        }
    }
}

This is log error when I run the program (second time)

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$1.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$1.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..

UPDATE

I create sampleProject at Github. Hope this sample helpful. Thank you


回答1:


There are two parts to this: the first concerns your code and the second is what the OGM should do when it encounters this scenario.

MachineSectionSummary has a field called Double percentDuration. When you initialise your database it sets every instance to 0.0. The first time you run /initMachineSectionSummary it calls updateMachineSectionSummary()

The line that introduces the issue is here: Double percentDurationTotal = (durationTotal / durationTotal) * 100.0;. The expression that creates durationTotal always returns 0.0. This calculation will result in a NaN which we then set on MachineSectionSummary.percentDuration. The OGM then saves this value to Neo4j. The problem occurs as you have found out when you try to retrieve the NaN value from the database and map it back to a MachineSectionSummary. The OGM at this point is expecting a Double but gets a String called "NaN" instead and it blows up with the exception: java.lang.IllegalArgumentException: argument type mismatch.

Having worked on a lot of numerical projects in the past my recommendation would be to prevent NaN from appearing; that is do some defensive coding where it could potentially originate. That should fix your primary issue.

This introduces the second issue: what do we expect the OGM to do here? In some cases some users may want to store NaN in the database. Some users may want to make sure NaN's are always null. Either way the OGM should probably alert developers with a better error message.



来源:https://stackoverflow.com/questions/40082468/spring-data-neo4j-argument-type-mismatch

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!