Corda帐户:“ id”列中的错误null值违反了非null约束

时间:2019-11-22 08:56:55

标签: corda

我正在使用带区域约束的开放源代码运行的帐户测试Corda 4.3。
我有4个节点,分别是Node A,Node B,Node C和Notary(Notary是Corda 4.1的CE版本),并使用PostgreSQL作为数据库。

首先,我在节点A上创建一个帐户 testadm1 并与节点B共享
然后我在节点B上创建一个帐户 seller1 seller2 并与节点A共享

使用以下流程

CreateAccountFlow

@StartableByRPC
@StartableByService
@InitiatingFlow
class CreateNewAccount(private val acctName:String) : FlowLogic<String>() {

    @Suspendable
    override fun call(): String {
        //Create a new account
        val newAccount = accountService.createAccount(name = acctName).toCompletableFuture().getOrThrow()
        val acct = newAccount.state.data
        return ""+acct.name + " team's account was created. UUID is : " + acct.identifier
    }
}

ShareAccountFlow

@StartableByRPC
@StartableByService
@InitiatingFlow
class ShareAccountTo(private val acctNameShared: String,
                     private val shareTo: Party) : FlowLogic<String>(){

    @Suspendable
    override fun call(): String {

        //Create a new account
        val allmyAccounts = accountService.ourAccounts()
        val sharedAccount = allmyAccounts.single { it.state.data.name == acctNameShared }.state.data.identifier.id
        accountService.shareAccountInfoWithParty(sharedAccount,shareTo)

        return "Shared " + acctNameShared + " with " + shareTo.name.organisation
    }
}

然后我尝试使用以下流程从节点A上的testadm1帐户向节点B上的Seller1帐户发行StateA:

object IssueStateA {

    @InitiatingFlow
    @StartableByRPC
    class Initiator(private val documentNumber: String,
                    private val amount: BigDecimal,
                    private val whoAmI: String,
                    private val whereTo: String) : FlowLogic<SignedTransaction>() {

        private lateinit var myKey: PublicKey
        private lateinit var myAnonymousParty: AnonymousParty
        private lateinit var targetAcctAnonymousParty: AnonymousParty

        @Suspendable
        override fun call(): SignedTransaction {

            logger.info("IssueStateA whoAmI: $whoAmI")
            val myAccount = accountService.accountInfo(whoAmI).single().state.data
            logger.info("IssueStateA myAccount: $myAccount")
            myKey = subFlow(NewKeyForAccount(myAccount.identifier.id)).owningKey
            logger.info("IssueStateA myKey: $myKey")
            myAnonymousParty = AnonymousParty(myKey)
            logger.info("IssueStateA myAnonymousParty: $myAnonymousParty")

            logger.info("IssueStateA whereTo: $whereTo")
            val targetAccount = accountService.accountInfo(whereTo).single().state.data
            logger.info("IssueStateA targetAccount: $targetAccount")
            targetAcctAnonymousParty = subFlow(RequestKeyForAccount(targetAccount))
            logger.info("IssueStateA targetAcctAnonymousParty: $targetAcctAnonymousParty")

            val (stx, sessions) = collectSignature(verifyAndSign(build()))
            return subFlow(FinalityFlow(stx, sessions))
        }

        private fun build(): TransactionBuilder {

            val stateOut = StateA(
                buyer = myAnonymousParty, 
                documentNumber = documentNumber,
                lifecycle = StateAContract.Lifecycle.ISSUED,
                seller = targetAcctAnonymousParty,
                amount = amount
            )

            val result = TransactionBuilder(firstNotary).apply {
                // Add outputs
                withItems(StateAndContract(stateOut, StateAContract.CONTRACT_ID))
                // Add commands
                addCommand(StateAContract.Commands.Test(), listOf(targetAcctAnonymousParty.owningKey, myKey))
            }

            return result.toLedgerTransaction(serviceHub)
        }

        private fun verifyAndSign(transaction: TransactionBuilder): SignedTransaction {
            transaction.verify(serviceHub)
            return serviceHub.signInitialTransaction(transaction)
        }

        @Suspendable
        private fun collectSignature(transaction: SignedTransaction): Pair<SignedTransaction, Set<FlowSession>> {
            val sessions = transaction.sessionsOfParticipants()
            return subFlow(CollectSignaturesFlow(
                    transaction,
                    sessions,
                    listOf(ourIdentity.owningKey, myKey))) to sessions
        }
    }

    @InitiatedBy(Initiator::class)
    class Responder(private val otherFlow: FlowSession) : FlowLogic<SignedTransaction>() {

        @Suspendable
        override fun call(): SignedTransaction {
            return subFlow(ReceiveFinalityFlow(otherFlow))
        }
    }
}

我得到了这个错误

[INFO ] 2019-11-22T10:40:39,364 [Node thread-1] flow - IssueStateA whoAmI: testadm1
[INFO ] 2019-11-22T10:40:39,402 [Node thread-1] flow - IssueStateA myAccount: AccountInfo(name=testadm1, host=OU=BUYER, O=BUYER, L=Bangkok, C=TH, identifier=67cd26fc-fe02-4c9e-8c9a-b98f41496e8f)
[INFO ] 2019-11-22T10:40:39,431 [Node thread-1] PersistentIdentityService - Linking: D64237126C615F97B9420ED201E37B3E199B97F8F0880357C4E31C18937B52C4 to OU=BUYER, O=BUYER, L=Bangkok, C=TH
[INFO ] 2019-11-22T10:40:39,440 [Node thread-1] flow - IssueStateA myKey: net.i2p.crypto.eddsa.EdDSAPublicKey@eed1fc59
[INFO ] 2019-11-22T10:40:39,447 [Node thread-1] flow - IssueStateA myAnonymousParty: Anonymous(DLFRNotAZwt3RaUFjuVqsv3JjvsLamKN1BScBadL1gj8PD)
[INFO ] 2019-11-22T10:40:39,647 [Node thread-1] flow - IssueStateA whereTo: seller1
[WARN ] 2019-11-22T10:40:39,897 [Node thread-1] SqlExceptionHelper - SQL Error: 0, SQLState: 23502
[ERROR] 2019-11-22T10:40:39,897 [Node thread-1] SqlExceptionHelper - ERROR: null value in column "id" violates not-null constraint
  Detail: Failing row contains (67cd26fc-fe02-4c9e-8c9a-b98f41496e8f, DL8sNJsBnTyvt83LoqYTScYMKUzLqfc4uoK6XfNfaezMRu, null).
[INFO ] 2019-11-22T10:40:39,898 [Node thread-1] flow - Flow raised an error: An error occurred while attempting to query the vault: org.hibernate.exception.ConstraintViolationException: could not execute statement. Sending it to flow hospital to be triaged.
[INFO ] 2019-11-22T10:40:39,906 [Node thread-1] StaffedFlowHospital - Flow [120a930d-bbbc-476d-b8ee-e8021346edd7] admitted to hospital in state StateMachineState(checkpoint=Checkpoint(invocationContext=InvocationContext(origin=RPC(actor=Actor(id=Id(value=dvcorda), serviceId=AuthServiceId(value=NODE_CONFIG), owningLegalIdentity=OU=BUYER, O=BUYER, L=Bangkok, C=TH)), trace=Trace(invocationId=73077172-0acc-465f-ab58-9cd9216d5850, timestamp: 2019-11-22T03:40:37.932Z, entityType: Invocation, sessionId=ade28825-50f4-40d2-a25e-4169b56cd2b6, timestamp: 2019-11-22T03:36:33.392Z, entityType: Session), actor=Actor(id=Id(value=dvcorda), serviceId=AuthServiceId(value=NODE_CONFIG), owningLegalIdentity=OU=BUYER, O=BUYER, L=Bangkok, C=TH), externalTrace=null, impersonatedActor=null), ourIdentity=OU=BUYER, O=BUYER, L=Bangkok, C=TH, sessions={}, subFlowStack=[Initiating(flowClass=class com.example.test.corda.flows.IssueStateA$Initiator, classToInitiateWith=class com.example.test.corda.flows.IssueStateA$Initiator, flowInfo=FlowInfo(flowVersion=1, appName=flow-1.0), subFlowVersion=CoreFlow(platformVersion=5), isEnabledTimedFlow=false)], flowState=Unstarted(flowStart=Explicit, frozenFlowLogic=4E5FA956E081EB2C71F938337E6A00A43CCA0918CC7CED4D294464CC99F6D82E), errorState=Clean, numberOfSuspends=0), flowLogic=com.example.test.corda.flows.IssueStateA$Initiator@42d83fae, pendingDeduplicationHandlers=[], isFlowResumed=true, isTransactionTracked=false, isAnyCheckpointPersisted=true, isStartIdempotent=false, isRemoved=false, senderUUID=null)
[INFO ] 2019-11-22T10:40:39,907 [Node thread-1] StaffedFlowHospital - Error 1 of 1:net.corda.core.node.services.VaultQueryException: An error occurred while attempting to query the vault: org.hibernate.exception.ConstraintViolationException: could not execute statement
        at net.corda.node.services.vault.NodeVaultService._queryBy(NodeVaultService.kt:573) ~[corda-node-4.3.jar:?]
        at com.r3.corda.lib.accounts.workflows.services.KeyManagementBackedAccountService.accountInfo(KeyManagementBackedAccountsService.kt:133) ~[?:?]
        at com.example.test.corda.flows.IssueStateA$Initiator.call(IssueStateA.kt:23) ~[?:?]
        at com.example.test.corda.flows.IssueStateA$Initiator.call(IssueStateA.kt:5) ~[?:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:270) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.statemachine.FlowStateMachineImpl.run(FlowStateMachineImpl.kt:46) ~[corda-node-4.3.jar:?]
        at co.paralleluniverse.fibers.Fiber.run1(Fiber.java:1092) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at co.paralleluniverse.fibers.Fiber.exec(Fiber.java:788) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at co.paralleluniverse.fibers.RunnableFiberTask.doExec(RunnableFiberTask.java:100) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at co.paralleluniverse.fibers.RunnableFiberTask.run(RunnableFiberTask.java:91) ~[quasar-core-0.7.10-jdk8.jar:0.7.10]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) ~[?:1.8.0_222]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) ~[?:1.8.0_222]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.access$201(ScheduledThreadPoolExecutor.java:180) ~[?:1.8.0_222]
        at java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask.run(ScheduledThreadPoolExecutor.java:293) ~[?:1.8.0_222]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149) ~[?:1.8.0_222]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624) ~[?:1.8.0_222]
        at net.corda.node.utilities.AffinityExecutor$ServiceAffinityExecutor$1$thread$1.run(AffinityExecutor.kt:63) ~[corda-node-4.3.jar:?]
Caused by: javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: could not execute statement
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:154) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:181) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.ExceptionConverterImpl.convert(ExceptionConverterImpl.java:188) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1489) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1469) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.loadValue(AppendOnlyPersistentMap.kt:200) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.access$loadValue(AppendOnlyPersistentMap.kt:24) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$transactionalLoadValue$3.invoke(AppendOnlyPersistentMap.kt:224) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown$valueWithoutIsolationDelegate$1.invoke(AppendOnlyPersistentMap.kt:315) ~[corda-node-4.3.jar:?]
        at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown.isPresent(AppendOnlyPersistentMap.kt:313) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional.orElse(AppendOnlyPersistentMap.kt:286) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.get(AppendOnlyPersistentMap.kt:41) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage$getTransaction$1.invoke(DBTransactionStorage.kt:178) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage$getTransaction$1.invoke(DBTransactionStorage.kt:31) ~[corda-node-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220) ~[corda-node-api-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage.getTransaction(DBTransactionStorage.kt:177) ~[corda-node-4.3.jar:?]
        at net.corda.node.internal.ServicesForResolutionImpl.loadStates(ServicesForResolutionImpl.kt:36) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService$_queryBy$2.invoke(NodeVaultService.kt:665) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService$_queryBy$2.invoke(NodeVaultService.kt:54) ~[corda-node-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220) ~[corda-node-api-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService._queryBy(NodeVaultService.kt:587) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService._queryBy(NodeVaultService.kt:569) ~[corda-node-4.3.jar:?]
        ... 16 more
Caused by: org.hibernate.exception.ConstraintViolationException: could not execute statement
        at org.hibernate.exception.internal.SQLStateConversionDelegate.convert(SQLStateConversionDelegate.java:112) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:42) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:113) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.engine.jdbc.spi.SqlExceptionHelper.convert(SqlExceptionHelper.java:99) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:178) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3181) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3695) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:90) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1483) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1469) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.loadValue(AppendOnlyPersistentMap.kt:200) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.access$loadValue(AppendOnlyPersistentMap.kt:24) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$transactionalLoadValue$3.invoke(AppendOnlyPersistentMap.kt:224) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown$valueWithoutIsolationDelegate$1.invoke(AppendOnlyPersistentMap.kt:315) ~[corda-node-4.3.jar:?]
        at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown.isPresent(AppendOnlyPersistentMap.kt:313) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional.orElse(AppendOnlyPersistentMap.kt:286) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.get(AppendOnlyPersistentMap.kt:41) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage$getTransaction$1.invoke(DBTransactionStorage.kt:178) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage$getTransaction$1.invoke(DBTransactionStorage.kt:31) ~[corda-node-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220) ~[corda-node-api-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage.getTransaction(DBTransactionStorage.kt:177) ~[corda-node-4.3.jar:?]
        at net.corda.node.internal.ServicesForResolutionImpl.loadStates(ServicesForResolutionImpl.kt:36) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService$_queryBy$2.invoke(NodeVaultService.kt:665) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService$_queryBy$2.invoke(NodeVaultService.kt:54) ~[corda-node-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220) ~[corda-node-api-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService._queryBy(NodeVaultService.kt:587) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService._queryBy(NodeVaultService.kt:569) ~[corda-node-4.3.jar:?]
        ... 16 more
Caused by: org.postgresql.util.PSQLException: ERROR: null value in column "id" violates not-null constraint
  Detail: Failing row contains (67cd26fc-fe02-4c9e-8c9a-b98f41496e8f, DL8sNJsBnTyvt83LoqYTScYMKUzLqfc4uoK6XfNfaezMRu, null).
        at org.postgresql.core.v3.QueryExecutorImpl.receiveErrorResponse(QueryExecutorImpl.java:2440) ~[postgresql-42.2.5.jar:42.2.5]
        at org.postgresql.core.v3.QueryExecutorImpl.processResults(QueryExecutorImpl.java:2183) ~[postgresql-42.2.5.jar:42.2.5]
        at org.postgresql.core.v3.QueryExecutorImpl.execute(QueryExecutorImpl.java:308) ~[postgresql-42.2.5.jar:42.2.5]
        at org.postgresql.jdbc.PgStatement.executeInternal(PgStatement.java:441) ~[postgresql-42.2.5.jar:42.2.5]
        at org.postgresql.jdbc.PgStatement.execute(PgStatement.java:365) ~[postgresql-42.2.5.jar:42.2.5]
        at org.postgresql.jdbc.PgPreparedStatement.executeWithFlags(PgPreparedStatement.java:143) ~[postgresql-42.2.5.jar:42.2.5]
        at org.postgresql.jdbc.PgPreparedStatement.executeUpdate(PgPreparedStatement.java:120) ~[postgresql-42.2.5.jar:42.2.5]
        at com.zaxxer.hikari.pool.ProxyPreparedStatement.executeUpdate(ProxyPreparedStatement.java:61) ~[HikariCP-3.3.1.jar:?]
        at com.zaxxer.hikari.pool.HikariProxyPreparedStatement.executeUpdate(HikariProxyPreparedStatement.java) ~[HikariCP-3.3.1.jar:?]
        at org.hibernate.engine.jdbc.internal.ResultSetReturnImpl.executeUpdate(ResultSetReturnImpl.java:175) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3181) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.persister.entity.AbstractEntityPersister.insert(AbstractEntityPersister.java:3695) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.action.internal.EntityInsertAction.execute(EntityInsertAction.java:90) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:604) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.engine.spi.ActionQueue.executeActions(ActionQueue.java:478) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.event.internal.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:356) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.event.internal.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:39) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.SessionImpl.doFlush(SessionImpl.java:1483) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at org.hibernate.internal.SessionImpl.flush(SessionImpl.java:1469) ~[hibernate-core-5.4.3.Final.jar:5.4.3.Final]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.loadValue(AppendOnlyPersistentMap.kt:200) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.access$loadValue(AppendOnlyPersistentMap.kt:24) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$transactionalLoadValue$3.invoke(AppendOnlyPersistentMap.kt:224) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown$valueWithoutIsolationDelegate$1.invoke(AppendOnlyPersistentMap.kt:315) ~[corda-node-4.3.jar:?]
        at kotlin.SafePublicationLazyImpl.getValue(LazyJVM.kt:107) ~[kotlin-stdlib-1.2.71.jar:1.2.71-release-64 (1.2.71)]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional$Unknown.isPresent(AppendOnlyPersistentMap.kt:313) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase$Transactional.orElse(AppendOnlyPersistentMap.kt:286) ~[corda-node-4.3.jar:?]
        at net.corda.node.utilities.AppendOnlyPersistentMapBase.get(AppendOnlyPersistentMap.kt:41) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage$getTransaction$1.invoke(DBTransactionStorage.kt:178) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage$getTransaction$1.invoke(DBTransactionStorage.kt:31) ~[corda-node-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220) ~[corda-node-api-4.3.jar:?]
        at net.corda.node.services.persistence.DBTransactionStorage.getTransaction(DBTransactionStorage.kt:177) ~[corda-node-4.3.jar:?]
        at net.corda.node.internal.ServicesForResolutionImpl.loadStates(ServicesForResolutionImpl.kt:36) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService$_queryBy$2.invoke(NodeVaultService.kt:665) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService$_queryBy$2.invoke(NodeVaultService.kt:54) ~[corda-node-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:235) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:214) ~[corda-node-api-4.3.jar:?]
        at net.corda.nodeapi.internal.persistence.CordaPersistence.transaction(CordaPersistence.kt:220) ~[corda-node-api-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService._queryBy(NodeVaultService.kt:587) ~[corda-node-4.3.jar:?]
        at net.corda.node.services.vault.NodeVaultService._queryBy(NodeVaultService.kt:569) ~[corda-node-4.3.jar:?]
        ... 16 more

这是StateA的样子

@BelongsToContract(StateAContract::class)
data class StateA(
        val buyer: AnonymousParty,
        val documentNumber: String,
        val issuedDate: Instant = Instant.now(),
        val lifecycle: StateAContract.Lifecycle,
        val seller: AnonymousParty,
        val amount: BigDecimal,
        override val linearId: UniqueIdentifier = UniqueIdentifier()) : LinearState, QueryableState {

   override val participants: List<AbstractParty> get() = listOf(buyer, seller)

   override fun supportedSchemas(): Iterable<MappedSchema> = listOf(StateASchema)

   override fun generateMappedObject(schema: MappedSchema): PersistentState {
      if (schema is StateASchema) {
          return StateASchema.StateAEntity(
               buyer = buyer,
               documentNumber = documentNumber,
               issuedDate = issuedDate,
               lifecycle = lifecycle.toString(),
               seller = seller,
               amount = amount.quantity
          )
      } else {
          throw IllegalStateException("Cannot construct instance of ${this.javaClass} from Schema: $schema")
      }
  }
}

这是Schema类

object StateSchema

object StateASchema : MappedSchema(
        schemaFamily = StateSchema::class.java,
        version = 1,
        mappedTypes = listOf(StateA::class.java)
)

@Entity
@Table(name = "stateA")
data class StateAEntity(

   @Column(name = "linear_id")
   var linearId: String? = null,

   @Column(name = "buyer")
   val buyer: AbstractParty? = null,

   @Column(name = "external_id")
   var documentNumber: String? = null,

   @Column(name = "issued_date")
   var issuedDate: Instant? = null,

   @Column(name = "seller")
   val seller: AbstractParty? = null,

   @Column(name = "amount")
   val amount: BigDecimal? = null

) : PersistentState()

我已经检查了我的postgres数据库,并使用此sql在帐户表中看到节点A具有节点B的帐户

select * from accounts
join vault_states
on vault_states.transaction_id = accounts.transaction_id
and vault_states.output_index = accounts.output_index
and vault_states.state_status = 0

我做错了什么还是我错过了什么?

2 个答案:

答案 0 :(得分:1)

我找到了根本原因

首先,我以Corda 4.1版启动该节点,并创建具有3列 external_id,public_key_hash id (不为null)

的表pk_hash_to_ext_id_map表

但是我不对数据库做任何事情就将Corda版本更改为4.3。我认为在4.3中,它不再需要 id ,因此当它尝试放入数据库时​​,它会将id发送为null。

所以我要做的是清除数据库并重新启动所有节点,现在重新启动带有2列 external_id,public_key_hash 的pk_hash_to_ext_id_map表,

答案 1 :(得分:0)

我怀疑这是您的generateMappedObject函数。我认为您不希望返回StateA,因为它不是PersistentState。您可以创建一个PersistentState并返回它吗?

有关示例,请参见here