我正在使用带区域约束的开放源代码运行的帐户测试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
我做错了什么还是我错过了什么?
答案 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。