如何在 Kotlin 的委托属性上放置 JPA 注释?
How do I put JPA annotations on delegated properties in Kotlin?
假设我有一个 JPA 实体,例如
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int? = null
@Column(name = "project_id")
var projectId: Int? = null
@Column(name = "plasmid_id")
var plasmidId: Int? = null
}
现在,我知道对于plasmid_reference
中的每个条目加入tablenone 这些属性可以为空。 (事实上,数据库强制执行此操作。)
如何告诉 Kotlin?
一种天真的方法是尝试 lateinit
...
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
lateinit var id: Int
@Column(name = "project_id")
lateinit var projectId: Int
@Column(name = "plasmid_id")
lateinit var plasmidId: Int
}
这甚至无法编译。
'lateinit' modifier is not allowed on properties of primitive types
好的,让我们使用建议的解决方案并转换为使用委托。
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id by notNull<Int>()
@Column(name = "project_id")
var projectId by notNull<Int>()
@Column(name = "plasmid_id")
var plasmidId by notNull<Int>()
}
这仍然无法编译,因为
This annotation is not applicable to target 'member property with delegate'
好的……这听起来像是科特林的东西,在 Java 中,我会把注释扔到一个字段上,所以也许……
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@field:Id
@field:GeneratedValue(strategy = GenerationType.IDENTITY)
var id by notNull<Int>()
@field:Column(name = "project_id")
var projectId by notNull<Int>()
@field:Column(name = "plasmid_id")
var plasmidId by notNull<Int>()
}
不,事实证明,并非如此。仍然无法编译,因为
'@field:' annotations could be applied only to properties with backing fields
好吧,让我们注释一下“存储委托 属性 的委托实例的字段”(参见 https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets)
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@delegate:Id
@delegate:GeneratedValue(strategy = GenerationType.IDENTITY)
var id by notNull<Int>()
@delegate:Column(name = "project_id")
var projectId by notNull<Int>()
@delegate:Column(name = "plasmid_id")
var plasmidId by notNull<Int>()
}
这确实编译但会抛出运行时异常,因为
The attribute [plasmidId] is not present in the managed type [EntityTypeImpl@960932033:PlasmidReference
[ javaType: class com.[...].PlasmidReference descriptor: RelationalDescriptor(com.[...].PlasmidReference --> [DatabaseTable(plasmid_reference)]), mappings: 3]].
at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:151)
at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:635)
啊啊啊,我没主意了。
我该如何解决?
将其移至构造函数定义应该可以解决问题
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int? = null,
@Column(name = "project_id")
var projectId: Int,
@Column(name = "plasmid_id")
var plasmidId: Int
)
假设我有一个 JPA 实体,例如
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int? = null
@Column(name = "project_id")
var projectId: Int? = null
@Column(name = "plasmid_id")
var plasmidId: Int? = null
}
现在,我知道对于plasmid_reference
中的每个条目加入tablenone 这些属性可以为空。 (事实上,数据库强制执行此操作。)
如何告诉 Kotlin?
一种天真的方法是尝试 lateinit
...
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
lateinit var id: Int
@Column(name = "project_id")
lateinit var projectId: Int
@Column(name = "plasmid_id")
lateinit var plasmidId: Int
}
这甚至无法编译。
'lateinit' modifier is not allowed on properties of primitive types
好的,让我们使用建议的解决方案并转换为使用委托。
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id by notNull<Int>()
@Column(name = "project_id")
var projectId by notNull<Int>()
@Column(name = "plasmid_id")
var plasmidId by notNull<Int>()
}
这仍然无法编译,因为
This annotation is not applicable to target 'member property with delegate'
好的……这听起来像是科特林的东西,在 Java 中,我会把注释扔到一个字段上,所以也许……
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@field:Id
@field:GeneratedValue(strategy = GenerationType.IDENTITY)
var id by notNull<Int>()
@field:Column(name = "project_id")
var projectId by notNull<Int>()
@field:Column(name = "plasmid_id")
var plasmidId by notNull<Int>()
}
不,事实证明,并非如此。仍然无法编译,因为
'@field:' annotations could be applied only to properties with backing fields
好吧,让我们注释一下“存储委托 属性 的委托实例的字段”(参见 https://kotlinlang.org/docs/reference/annotations.html#annotation-use-site-targets)
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference {
@delegate:Id
@delegate:GeneratedValue(strategy = GenerationType.IDENTITY)
var id by notNull<Int>()
@delegate:Column(name = "project_id")
var projectId by notNull<Int>()
@delegate:Column(name = "plasmid_id")
var plasmidId by notNull<Int>()
}
这确实编译但会抛出运行时异常,因为
The attribute [plasmidId] is not present in the managed type [EntityTypeImpl@960932033:PlasmidReference
[ javaType: class com.[...].PlasmidReference descriptor: RelationalDescriptor(com.[...].PlasmidReference --> [DatabaseTable(plasmid_reference)]), mappings: 3]].
at org.eclipse.persistence.internal.jpa.metamodel.ManagedTypeImpl.getAttribute(ManagedTypeImpl.java:151)
at org.springframework.data.jpa.repository.query.QueryUtils.toExpressionRecursively(QueryUtils.java:635)
啊啊啊,我没主意了。
我该如何解决?
将其移至构造函数定义应该可以解决问题
@Entity
@Table(name = "plasmid_reference")
class PlasmidReference(
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
var id: Int? = null,
@Column(name = "project_id")
var projectId: Int,
@Column(name = "plasmid_id")
var plasmidId: Int
)