所以这是我的两难境地:我有一个域模型,在 scala 中有一堆案例类,例如 User 和 Organization。在我的数据访问层(dao、存储库等)中,我使用 astyanax(来自 netflix 的 java 库),它是实体持久化器,用于将对象保存到 cassandra 列族。
这是我的 cassandra/astyanax 支持的 DAO 的一些示例代码(是的,我知道我需要做一些更 scala-ish 的事情,但我仍在学习 =))
在阅读了这个冗长的描述之后,我基本上是想看看为什么当 java 在getDeclaredAnnotations() 上 getDeclaredAnnotations() 上 Field 时,参数列表中的带注释的 val 不起作用我不想不得不回去重构一切,以便我可以使用持久化器,这使得保存实体变得非常简单(即manager.put(entity))。如果我想继续使用案例类,以便可以使用更多不可变样式的 scala 和来自 scalaz 的 Lens,那么我将不得不更新 DAO 并手动执行所有持久化操作,这真的可以消磨时间。
所以,如果有人知道我没有看到的东西,请告诉我!提前感谢您抽出宝贵时间阅读本文。
场景 1 - 案例类
Astyanax 无法获取 val 上的注释 @Id
@实体
case class Organization(@Id @Column(name = "id") override val id: Option[UUID] = None,
@Column(name = "created_on") 覆盖 val createdOn: Option[Date] = None,
@Column(name = "modified_on") 覆盖 val modifiedOn: Option[Date] = None,
@Column(name = "name") 名称:选项 [字符串] = 无,
@Column(name = "is_paid_account") isPaidAccount: Boolean = false) 扩展 IdBaseEntity[UUID](id, createdOn, modifiedOn)
场景 2 - 有伴随对象的类或没有伴随对象的类
Astyanax 无法获取val 上的@Id 注释
@实体
类组织(@Id @Column(name = "id") 覆盖有效 id: Option[UUID] = None,
@Column(name = "created_on") 覆盖 val createdOn: Option[Date] = None,
@Column(name = "modified_on") 覆盖 val modifiedOn: Option[Date] = None,
@Column(name = "name") 名称:选项 [字符串] = 无,
@Column(name = "is_paid_account") isPaidAccount: Boolean = false) 扩展 IdBaseEntity[UUID](id, createdOn, modifiedOn)
对象组织{
def apply(id: Option[UUID] = None,
createdOn: 选项 [日期] = 无,
修改时间:选项 [日期] = 无,
名称:选项 [字符串] = 无,
isPaidAccount: Boolean = false) = new Organization(id, createdOn, modifiedOn, name, isPaidAccount)
}
场景 3 - 在块内定义 val 的案例类或类
这很好用,因为它会将theId 拾取为使用@Id 进行注释,但我不想这样做,因为IdBaseEntity 已经定义和id val 并破坏了继承和能够实现的整个目的将id 传递给超类
@实体
case class Organization(@Id @Column(name = "id") override val id: Option[UUID] = None,
@Column(name = "created_on") 覆盖 val createdOn: Option[Date] = None,
@Column(name = "modified_on") 覆盖 val modifiedOn: Option[Date] = None,
@Column(name = "name") 名称:选项 [字符串] = 无,
@Column(name = "is_paid_account") isPaidAccount: Boolean = false) 扩展 IdBaseEntity[UUID](id, createdOn, modifiedOn) {
@Id @Column(name = "id") val theId: Option[UUID] = id
}
数据访问部分
在经理中,您将看到对build() 的调用。 Astyanax 检查传递给withEntityType() 的类,在本例中为classOf[Organization]
当我在类块内声明了一个 val 而不是案例类或带有伴随对象的常规类/常规类的参数列表时,我的每个场景都失败了,除了 #3。 Astyanax 说该类的已知成员用@Id 注释,因此它会引发异常。在进一步挖掘之前,我想我会向社区询问注释 scala 类并将其发送到进行反射的 java 库的细微差别。来源没什么特别的。事实上,这是失败的相关行:https://github.com/Netflix/astyanax/blob/master/astyanax-entity-mapper/src/main/java/com/netflix/astyanax/entitystore/EntityMapper.java#L89-120
类 CassandraOrganizationDAO 扩展 BaseCassandraDAO[Organization, UUID](Astyanax.context) 与 OrganizationDAO {
val ColumnFamilyOrganizations: ColumnFamily[UUID, String] = new ColumnFamily[UUID, String](
“组织”,
TimeUUIDSerializer.get(),
StringSerializer.get(),
ByteBufferSerializer.get())
val ColumnFamilyOrganizationMembers: ColumnFamily[UUID, UUID] = new ColumnFamily[UUID, UUID](
“组织成员”,
TimeUUIDSerializer.get(),
TimeUUIDSerializer.get(),
DateSerializer.get())
val manager: EntityManager[Organization, UUID] = new DefaultEntityManager.Builder[Organization, UUID]()
.withEntityType(classOf[组织])
.withKeyspace(getKeyspace())
.withColumnFamily(ColumnFamilyOrganizations)
。建造()
// 类的其余部分被省略
}