gpt4 book ai didi

java - 为什么 astyanax (java) 无法在我的 scala 案例类参数列表中识别我的 @Id 注释值?

转载 作者:塔克拉玛干 更新时间:2023-11-01 22:49:17 26 4
gpt4 key购买 nike

所以这是我的困境:我有一个域模型,其中包含 scala 中的大量案例类,例如 UserOrganization。在我的数据访问层(dao、存储库等)中,我使用 astyanax(来自 netflix 的 java 库),它是将对象保存到 cassandra 列族的实体持久性。

这是我的 cassandra/astyanax 支持的 DAO 的一些示例代码(是的,我知道我需要做一些更像 scala 的东西,但我仍在学习 =))

在阅读了这个冗长的描述之后,我主要是想了解为什么当 java 在 Field< 上执行 getDeclaredAnnotations() 时,参数列表中带注释的 vals 将不起作用 我不愿意返回并重构所有内容,这样我就可以使用 persister,这使得保存实体变得非常简单(即 manager.put(entity))。如果我想继续使用案例类,以便我可以使用更多不可变样式的 scala 和来自 scalaz 的 Lens,那么我将不得不更新 DAO 并手动执行所有持久化操作,这真的可以消磨时间。

所以,如果有人知道我没有看到的东西,请告诉我!预先感谢您花时间阅读本文。

场景 1 - 案例类

Astyanax 无法获取 val 上的注解 @Id

@Entitycase class Organization(@Id @Column(name = "id") override val id: Option[UUID] = None,                        @Column(name = "created_on") override val createdOn: Option[Date] = None,                        @Column(name = "modified_on") override val modifiedOn: Option[Date] = None,                        @Column(name = "name") name: Option[String] = None,                        @Column(name = "is_paid_account") isPaidAccount: Boolean = false) extends IdBaseEntity[UUID](id, createdOn, modifiedOn)

场景 2 - 有伴生对象的类或没有伴生对象的类

Astyanax 无法获取 val 上的 @Id 注释

@Entityclass Organization(@Id @Column(name = "id") override val id: Option[UUID] = None,                       @Column(name = "created_on") override val createdOn: Option[Date] = None,                       @Column(name = "modified_on") override val modifiedOn: Option[Date] = None,                       @Column(name = "name") name: Option[String] = None,                       @Column(name = "is_paid_account") isPaidAccount: Boolean = false) extends IdBaseEntity[UUID](id, createdOn, modifiedOn)object Organization {  def apply(id: Option[UUID] = None,            createdOn: Option[Date] = None,            modifiedOn: Option[Date] = None,            name: Option[String] = None,            isPaidAccount: Boolean = false) = new Organization(id, createdOn, modifiedOn, name, isPaidAccount)}

场景 3 - 案例类或在 block 内定义了 val 的类

这很好用,因为它选择了 theId 作为注释的 @Id,但我不想这样做,因为 IdBaseEntity已经定义了 id val 并破坏了继承的全部目的,并且能够将 id 传递给父类(super class)

@Entitycase class Organization(@Id @Column(name = "id") override val id: Option[UUID] = None,                        @Column(name = "created_on") override val createdOn: Option[Date] = None,                        @Column(name = "modified_on") override val modifiedOn: Option[Date] = None,                        @Column(name = "name") name: Option[String] = None,                        @Column(name = "is_paid_account") isPaidAccount: Boolean = false) extends IdBaseEntity[UUID](id, createdOn, modifiedOn) {  @Id @Column(name = "id") val theId: Option[UUID] = id}

数据访问部分

在管理器中,您将看到对 build() 的调用。 Astyanax 检查传入 withEntityType() 的类,在本例中为 classOf[Organization]

除了#3,我的每个场景都失败了,因为我在类 block 中声明了一个 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

class CassandraOrganizationDAO extends BaseCassandraDAO[Organization, UUID](Astyanax.context) with OrganizationDAO {  val ColumnFamilyOrganizations: ColumnFamily[UUID, String] = new ColumnFamily[UUID, String](    "organizations",    TimeUUIDSerializer.get(),    StringSerializer.get(),    ByteBufferSerializer.get())  val ColumnFamilyOrganizationMembers: ColumnFamily[UUID, UUID] = new ColumnFamily[UUID, UUID](    "organization_members",    TimeUUIDSerializer.get(),    TimeUUIDSerializer.get(),    DateSerializer.get())  val manager: EntityManager[Organization, UUID] = new DefaultEntityManager.Builder[Organization, UUID]()    .withEntityType(classOf[Organization])    .withKeyspace(getKeyspace())    .withColumnFamily(ColumnFamilyOrganizations)    .build() // the rest of the class is omitted }

最佳答案

我遇到了类似的问题,在构造函数的字段中从未考虑过我的注释。事实上,我使用了 SpringData,并且不可能直接在字段上映射注释(如 @Indexed)。

要在案例类的构造函数中启用注释,您应该首先创建这种类:

object FixedScalaAnnotations {
type Id = com.packagecontainingid.Id @field //replace by the right package
type Column = com.packagecontainingcolumn.Column @field
}

然后将其导入到您的案例类中并使用它代替原来的:

import FixedScalaAnnotations._

@Entity
case class Organization(@Id @Column(name = "id") override val id: Option[UUID] = None,
@Column(name = "created_on") override val createdOn: Option[Date] = None,
@Column(name = "modified_on") override val modifiedOn: Option[Date] = None,
@Column(name = "name") name: Option[String] = None,
@Column(name = "is_paid_account") isPaidAccount: Boolean = false) extends IdBaseEntity[UUID](id, createdOn, modifiedOn)

确保未使用原始包。

这是一篇处理 JPA 的相关文章:http://blog.fakod.eu/2010/07/14/constructor-arguments-with-jpa-annotations/

关于java - 为什么 astyanax (java) 无法在我的 scala 案例类参数列表中识别我的 @Id 注释值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16348668/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com