所以这是我的困境:我有一个域模型,在 scala 中有一堆案例类,例如User
和Organization
. 在我的数据访问层(dao、存储库等)中,我使用 astyanax(来自 netflix 的 java 库),它是实体持久化器,用于将对象保存到 cassandra 列族。
这是我的 cassandra/astyanax 支持的 DAO 的一些示例代码(是的,我知道我需要做一些更 scala-ish 的事情,但我仍在学习 =))
getDeclaredAnnotations()
在阅读了这个冗长的描述之后,我基本上是想看看为什么当 java 执行时参数列表中的带注释的 val 不起作用Field
我不想回去重构所有东西,这样我就可以使用持久化使保存实体(即manager.put(entity)
)变得非常简单。如果我想继续使用案例类,以便可以使用更多不可变样式的 scala 和Lens
scalaz,那么我将不得不更新 DAO 并手动执行所有持久化操作,这真的可以消磨时间。
所以,如果有人知道我没有看到的东西,请告诉我!提前感谢您花时间阅读本文。
场景 1 - 案例类
Astyanax 无法获取注释 @Id onval
@实体 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 无法获取 @Id 注释val
@实体 类组织(@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
已经定义了 andid 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]
我的每个场景都失败了,除了#3,当我在类块内声明了一个 val 而不是案例类或带有伴随对象的常规类/常规类的参数列表时。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) 。建造() // 类的其余部分被省略 }