Corda扩展FungibleState自定义Schema时遇InstantiationException问题求助
解决Corda自定义Schema中的Hibernate InstantiationException错误
我之前也碰到过一模一样的问题,核心原因就是Hibernate要求实体类必须有一个无参构造函数,但Kotlin默认情况下不会自动生成——尤其是当你的Schema类里有非空属性的时候。虽然你已经装了kotlin-jpa插件,但可能还有一些细节没处理到位,下面给你几个靠谱的解决思路:
1. 确保kotlin-jpa插件正确配置
先检查你的build.gradle(contracts模块的)里有没有正确引入插件,版本要和Corda自带的Kotlin版本匹配:
plugins { id 'org.jetbrains.kotlin.plugin.jpa' version '1.6.21' // 替换成和Corda兼容的版本 }
插件的作用是自动为JPA实体生成无参构造,但有时候如果配置位置不对(比如没加到contracts模块),就不会生效。
2. 显式添加无参构造函数
如果插件没起作用,最直接的办法就是手动给Schema类加一个无参构造,给每个非空属性设置合理的默认值:
@Entity @Table(name = "custom_fungible_states") class CustomFungibleSchemaV1( @Column(name = "owner") var owner: AbstractParty, @Column(name = "amount") var amount: Amount<Currency>, @Column(name = "issuer") var issuer: AbstractParty ) : PersistentState() { // 手动添加无参构造,给所有属性设默认值 constructor() : this( AnonymousParty(PublicKey.empty()), Amount(0, Currency.getInstance("USD")), AnonymousParty(PublicKey.empty()) ) }
这样Hibernate就能通过这个无参构造实例化你的实体类了。
3. 给字段设置可空或默认值
你提到把所有字段设为可空能解决问题,这是因为Kotlin会为全可空属性的类自动生成无参构造(默认值都是null)。如果业务允许,这是最简单的方案:
@Entity @Table(name = "custom_fungible_states") class CustomFungibleSchemaV1( @Column(name = "owner") var owner: AbstractParty? = null, @Column(name = "amount") var amount: Amount<Currency>? = null, @Column(name = "issuer") var issuer: AbstractParty? = null ) : PersistentState()
如果不想让字段可空,也可以给每个非空属性直接设置默认值,Kotlin同样会生成无参构造:
@Entity @Table(name = "custom_fungible_states") class CustomFungibleSchemaV1( @Column(name = "owner") var owner: AbstractParty = AnonymousParty(PublicKey.empty()), @Column(name = "amount") var amount: Amount<Currency> = Amount(0, Currency.getInstance("USD")), @Column(name = "issuer") var issuer: AbstractParty = AnonymousParty(PublicKey.empty()) ) : PersistentState()
额外注意点
- 你的Schema类必须继承自
PersistentState,这是Corda Vault查询要求的基础类; - 检查所有JPA注解(
@Entity、@Table、@Column)是否正确应用,有没有拼写错误; - 如果用了Kotlin数据类,要注意数据类的构造函数特性——有时候换成普通类更容易控制构造逻辑。
内容的提问来源于stack exchange,提问作者Matthieu Merlyn
相关产品推荐
相关产品推荐

