问题
A strategic question… When a state is going to have one to many type of data, should we always create a collection under the parent state object or create a separate state object for the child with the reference to parent? Example (Employer 1:M Employee) or (Employer 1:M Location) …. When to decide which strategy? I've listed some PROS & CONS for each. Not sure when to use what strategy. Looking for some feedback
Adding child as collection
PROS
=====
- Easier to manage from coding standpoint
- Easy access to child data as it will always be available when querying parent from vault
CONS
=====
- As each collection object is going to be represented as separate table in the database, Each time a new state is created child data is also replicated even though there may not be update on child which will cause database to grow unessential
- If we have too many of such collection objects then serialized transaction size could be huge so performance could be worst
Adding child as Separate State Object
PROS
=====
- Child data is not replicated with each time a new parent state is updated
- When there is an update on any of the Child data only that state needs to be communicated other participant
CONS
=====
- More coding needed in order to manage child state object separately
- Child data won't be available when querying parent from vault
- Each state needs to have its own contract so child objects can't be validated on the same parent contract
回答1:
Since states are linked to persisting to a single table on the backend, it is difficult to manage child collections. At present, I think you would need to leave the collection property unbound (i.e. not mapped to a database column and marked as transient so that the class can still be serializable) and then do a separate filtered query for the child records that can be assigned to the collection property of the state. Then when any change is persisted, it will not try to persist the child records. Changes to child records should be done individually through their own state transactions. It would be nice if Corda had a feature that would support the JPA feature of doing joins between tables such as @OneToMany. This would facilitate queries, but persisting state changes would still need to be handled separately. There may be a way of doing this that I am unaware of.
回答2:
It's an old question, but there does not seem to be an accepted answer, so I'll have a go.
Firstly, the Corda node is not just a back-end for your application, it's a node in a decentralised transaction processing system. The latter must be key requirement for you, otherwise you wouldn't use Corda.
Secondly, Corda implements UTXO (Unspent Transaction Output) paradigm for evolving distributed state through a series of transaction whereby a collection of objects representing input states are 'spent' (or consumed, become unavailable) and replaced by another collection of objects representing output states. The state objects themselves may have complex structures, but when they evolve they meant to be swapped as a whole. That is unlike, say, Ethereum or Hyperledger, where the global state is basically a large collection of unrelated key-value pairs that can change arbitrarily. UTXO model allows to easily implement features that are very hard to achieve with the global state model, such as transaction privacy. Important point here is that Corda can be made to emulate global state model, but it will be inefficient at it and lose most of its benefits.
Because of this, the way states are modelled must be based on the intended evolution of the distributed state of a CorDapp. The questions to ask yourself therefore are probably the following:
- Will the child states 'live their own life', i.e. evolve independently from the parent states? An example of a 'yes' would be Corda Token SDK, whereby token type and tokens themselves are separate states despite obvious parent-child relationship. Network participants can trade the child states without controlling the parent state.
- Will there be a need to withhold the information in a parent state but not the child, or vice versa from a party participating in a transaction? An example of a 'yes' would be the use of Oracle to sign off a child state object output without being shown the parent. Corda IRS example does something similar with transaction tear-offs when the Oracle fixes the interest rate.
- Will there be a situation whereby a network participant may need to know (i.e. keep in the vault) the child state, but not the parent state. An example of a 'yes' would be an off-ledger settlement workflow similar to the Corda Settler example, whereby paying agents can be settling obligations without necessarily knowing the details of the agreements that led to the obligations to arise.
If the answer to any of the above questions is 'yes', then you have to represent the children as separate states, otherwise it is better to leave them embedded into the parent state.
来源:https://stackoverflow.com/questions/50882846/corda-state-management-best-practice