4

I want to create State with unique id in database. There is my State code

data class SampleState(
    val partyA: Party,
    val partyB: Party,
    val value: Int,
    val id: String,
    override val linearId: UniqueIdentifier = UniqueIdentifier(id),
    val properties: LCProperties = LCProperties("ABC"))    : LinearState {...}

When I commit two similar SampleState, there are two different State in database with two different linearId. So, There are anyone can talk me that how to ensure that the "id" of a object of SampleState in database is unique? I used same code for catch this case in Flows and Contracts like

  val results = builder {

        val quantityIndex = SampleSchemaV1.PersistentSample::id.equal(id);

        val customCriteria1 = QueryCriteria.VaultCustomQueryCriteria(quantityIndex)

        val criteria = generalCriteria.and(customCriteria1);

        serviceHub.vaultService.queryBy<SampleState>(criteria)
    }
    if(results.states.count() > 0)
        throw IllegalArgumentException("id $id is exist")

However, it do not work with two commit Sample State Transaction in a near similar time even that in 1s (commit Transaction 1, and after 1 second, commit Transaction 2)

Henry
  • 191
  • 6

1 Answers1

0

In your state code, it is this line:

override val linearId: UniqueIdentifier = UniqueIdentifier(id)

That creates a unique id for you. The id that you are passing into UniqueIdentifier binds the unique id that is generated to your id. However all equality and comparison are based on the unique ID only.

Take a look at UniqueIdentifier.kt in the source code and you'll see this is the underlying code:

data class UniqueIdentifier(val externalId: String? = null, val id: UUID = UUID.randomUUID()) : Comparable<UniqueIdentifier> {
    override fun toString(): String = if (externalId != null) "${externalId}_$id" else id.toString()

This is a good post about how good Java's randomUUID is in ensuring an id is unique

You can also read more about UniqueIdentifier here

Cais Manai
  • 966
  • 1
  • 9
  • 20
  • So, in Corda, there are anyway to ensure that two similar States are stored in database? For example, in my example code above, I don't want to store two SampleStates with similar PartyA, PartyB, value and id. – Henry Aug 30 '18 at 02:07
  • Can you give them the same external ID? Their id would still remain unique, but you would be able to query based on this same external ID. – Cais Manai Aug 30 '18 at 16:35
  • 1
    @CaisManai even if you pass in the same UUID to two different linear ID states, Corda has no constraint to enforce uniqueness of these, meaning you can have multiple unconsumed states in the vault, all with the same type and linear ID. – Matthew Layton Sep 15 '19 at 13:58