问题
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