适用于Hazelcast的便携版本:将日期转换为长引发谓词中的异常

时间:2017-07-20 19:10:59

标签: serialization hazelcast predicates

我正在尝试使用com.hazelcast.nio.serialization.VersionedPortable进行Customer类的序列化。默认情况下,这不支持日期序列化。所以我们需要将它转换为Long

@Override
public void writePortable(PortableWriter writer) throws IOException {
    if (dob != null) {
        Long dobLong = dob.getTime();
        writer.writeLong(DOB_FIELD, dobLong);
    } else {
        writer.writeLong(DOB_FIELD, -1);
    }
}

@Override
public void readPortable(PortableReader reader) throws IOException {
    if (reader.hasField(DOB_FIELD)) {
        Long dobLong = reader.readLong(DOB_FIELD);
        dob = dobLong == -1 ? null : new Date(dobLong);
    }
}

在CustomerService中我有findCustomersByDob,它使用com.hazelcast.query.Predicate

public Collection<Customer> findCustomersByDob(Date dobStart, Date dobEnd) {
    Predicate dobStartPredicate = Predicates.greaterEqual("dob", dobStart);
    Predicate dobEndPredicate = Predicates.lessThan("dob", dobEnd);
    Predicate andPredicate = Predicates.and(dobStartPredicate, dobEndPredicate);
    return idToCustomerMap.values(andPredicate);
}

at idToCustomerMap.values(andPredicate);我收到以下异常。

  

java.lang.IllegalArgumentException:无法将[Tue Jan 01 00:00:00 IST 1980]转换为long       在com.hazelcast.query.impl.TypeConverters $ LongConverter.convert(TypeConverters.java:159)       在com.hazelcast.query.impl.IndexImpl.convert(IndexImpl.java:154)       在com.hazelcast.query.impl.IndexImpl.getSubRecords(IndexImpl.java:148)       在com.hazelcast.query.Predicates $ GreaterLessPredicate.filter(Predicates.java:691)       在com.hazelcast.query.Predicates $ AndPredicate.filter(Predicates.java:477)       在com.hazelcast.query.impl.IndexService.query(IndexService.java:97)       在com.hazelcast.map.impl.operation.QueryOperation.run(QueryOperation.java:92)       在com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:137)       在com.hazelcast.spi.impl.operationservice.impl.OperationRunnerImpl.run(OperationRunnerImpl.java:309)       在com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.processPacket(OperationThread.java:142)       在com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.process(OperationThread.java:115)       在com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.doRun(OperationThread.java:101)       在com.hazelcast.spi.impl.operationexecutor.classic.OperationThread.run(OperationThread.java:76)       在------结束远程并开始本地堆栈跟踪------。(未知来源)       在com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.resolveApplicationResponse(InvocationFuture.java:384)       at com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.resolveApplicationResponseOrThrowException(InvocationFuture.java:334)       在com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.get(InvocationFuture.java:225)       在com.hazelcast.spi.impl.operationservice.impl.InvocationFuture.get(InvocationFuture.java:204)       在com.hazelcast.map.impl.client.AbstractMapQueryRequest.collectResults(AbstractMapQueryRequest.java:103)       在com.hazelcast.map.impl.client.AbstractMapQueryRequest.invoke(AbstractMapQueryRequest.java:77)       在com.hazelcast.client.impl.client.InvocationClientRequest.process(InvocationClientRequest.java:27)       at com.hazelcast.client.impl.ClientEngineImpl $ ClientPacketProcessor.processRequest(ClientEngineImpl.java:463)       在com.hazelcast.client.impl.ClientEngineImpl $ ClientPacketProcessor.run(ClientEngineImpl.java:379)       at java.util.concurrent.ThreadPoolExecutor.runWorker(Unknown Source)       at java.util.concurrent.ThreadPoolExecutor $ Worker.run(Unknown Source)       在java.lang.Thread.run(未知来源)       在com.hazelcast.util.executor.HazelcastManagedThread.executeRun(HazelcastManagedThread.java:76)       在com.hazelcast.util.executor.HazelcastManagedThread.run(HazelcastManagedThread.java:92)       在------结束远程并开始本地堆栈跟踪------。(未知来源)       在com.hazelcast.client.spi.impl.ClientInvocationFuture.resolveResponse(ClientInvocationFuture.java:147)       在com.hazelcast.client.spi.impl.ClientInvocationFuture.get(ClientInvocationFuture.java:114)       在com.hazelcast.client.spi.impl.ClientInvocationFuture.get(ClientInvocationFuture.java:89)       在com.hazelcast.client.spi.ClientProxy.invoke(ClientProxy.java:151)       在com.hazelcast.client.proxy.ClientMapProxy.values(ClientMapProxy.java:837)       在com.foo.hazelcast.client.services.CustomerServiceImpl.findCustomersByDob(CustomerServiceImpl.java:99)       在com.foo.hazelcast.client.services.CustomerServiceTest.searchCustomersByDobRange(CustomerServiceTest.java:104)       at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)       at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)       at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)       at java.lang.reflect.Method.invoke(Unknown Source)       在org.junit.runners.model.FrameworkMethod $ 1.runReflectiveCall(FrameworkMethod.java:50)       在org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)       在org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)       在org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)       在org.junit.internal.runners.statements.RunBefores.evaluate(RunBefores.java:26)       在org.springframework.test.context.junit4.statements.RunBeforeTestMethodCallbacks.evaluate(RunBeforeTestMethodCallbacks.java:75)       在org.springframework.test.context.junit4.statements.RunAfterTestMethodCallbacks.evaluate(RunAfterTestMethodCallbacks.java:86)       在org.springframework.test.context.junit4.statements.SpringRepeat.evaluate(SpringRepeat.java:84)       在org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)       在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:252)       在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.runChild(SpringJUnit4ClassRunner.java:94)       在org.junit.runners.ParentRunner $ 3.run(ParentRunner.java:290)       在org.junit.runners.ParentRunner $ 1.schedule(ParentRunner.java:71)       在org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)       在org.junit.runners.ParentRunner.access $ 000(ParentRunner.java:58)       在org.junit.runners.ParentRunner $ 2.evaluate(ParentRunner.java:268)       在org.springframework.test.context.junit4.statements.RunBeforeTestClassCallbacks.evaluate(RunBeforeTestClassCallbacks.java:61)       在org.springframework.test.context.junit4.statements.RunAfterTestClassCallbacks.evaluate(RunAfterTestClassCallbacks.java:70)       在org.junit.runners.ParentRunner.run(ParentRunner.java:363)       在org.springframework.test.context.junit4.SpringJUnit4ClassRunner.run(SpringJUnit4ClassRunner.java:191)       在org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:50)       在org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:459)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:675)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:382)       在org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:192)

虽然很明显异常是由于Date的这种特殊处理,但我想知道TypeConversion的确切原因。我读到Hazelcast以序列化形式维护数据。所以这应该不是问题吗?

另外,我如何克服这个问题?

编辑: 我通过在谓词中传递date.getTime()来解决这个问题

public Collection<Customer> findCustomersByDob(Date dobStart, Date dobEnd) {
    Predicate dobStartPredicate = Predicates.greaterEqual("dob", dobStart.getTime());
    Predicate dobEndPredicate = Predicates.lessThan("dob", dobEnd.getTime());
    Predicate andPredicate = Predicates.and(dobStartPredicate, dobEndPredicate);
    return idToCustomerMap.values(andPredicate);
}

我猜这是因为hazelcast以序列化的形式维护数据,因此当它试图将long与谓词中的日期进行比较时会感到困惑。

尽管如此,这种方法绝对不是更清洁。在Version Portable中有更清晰的方法来避免这种情况吗?

1 个答案:

答案 0 :(得分:2)

@ vinodhini-chockalingam,<script> $("#loginBtn").click(function () { var newWindow = window.open("http://127.0.0.1:64449/page10.html", "status=1", "toolbar=0", "location=0"); newWindow.userName = $("#userName").val(); newWindow.passWord = $("#passWord").val(); return newWindow; //alert should come in child popup alert(window.userName + " " + window.passWord); }); </script> 旨在使用不同的语言,而不仅仅是Java。所以你可以从NodeJs&amp;中写一个值。使用Portable从Java读取它。这就是为什么你不能直接将Portable对象写入Portable的原因。您需要将其转换为支持的类型。

由于你写的日期很长,Hazelcast认识到这个领域的时间很长。只有您知道这是一个日期字段。然后当你需要运行一个谓词时,由于你写这个字段的时间很长,Hazelcast期望一个很长的值来比较。这就是原因。