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

Adr*_*uez 3 java reflection annotations scala astyanax

所以这就是我的困境:我有一个域模型,在scala中有一堆case类,比如UserOrganization.在我的数据访问层(dao,存储库等)中,我使用的是astyanax(来自netflix的java库),它的实体持久化将对象保存到cassandra列族.

这是我的cassandra/astyanax支持的DAO的一些示例代码(是的,我知道我需要做更多的scala-ish,但我还在学习=))

通过这个啰嗦的描述看完后,我基本上想看看,为什么在参数列表中注释的瓦尔斯将无法正常工作时,Java并getDeclaredAnnotations()Field我会讨厌要回去和重构一切,所以我可以用它的持留保存实体(即manager.put(entity))非常简单.如果我想继续使用case类,以便我可以使用更多不可变的样式scala和Lensscalaz,那么我将不得不更新DAO并手动执行所有持久化操作,这可以真正消磨时间.

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

场景1 - 案例类

Astyanax没有拿起注释@Id val

@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)

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

Astyanax没有拿起@Id注释 val

@Entity
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)

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 - 在块内定义val的Case类或类

这样可以正常工作,因为它会theId被注释为@Id,但我不想这样做,因为IdBaseEntity已经定义id val并且破坏了继承的整个目的并且能够传递id给超类

@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) {
  @Id @Column(name = "id") val theId: Option[UUID] = id
}

数据访问部分

在经理的路上,你会看到一个电话build().Astyanax检查传入的类,withEntityType()在本例中是classOf[Organization]

除了#3,当我在类块中声明了val而不是case类的参数列表或带有伴随对象的常规类/常规类时,我的每个场景都会失败.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 
}

Mik*_*378 5

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

要在case类的构造函数中启用注释,首先应创建此类:

object FixedScalaAnnotations {
  type Id = com.packagecontainingid.Id @field //replace by the right package
  type Column = com.packagecontainingcolumn.Column @field
}
Run Code Online (Sandbox Code Playgroud)

然后在您的案例类中导入它并使用它而不是原始类:

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)
Run Code Online (Sandbox Code Playgroud)

确保不使用原始包.

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