为什么赢了';astyanax(java)能识别scala案例类参数列表中的@Id注释值吗?

为什么赢了';astyanax(java)能识别scala案例类参数列表中的@Id注释值吗?,java,scala,reflection,annotations,astyanax,Java,Scala,Reflection,Annotations,Astyanax,所以我的困境是:我有一个域模型,在scala中有一堆case类,比如User和Organization。在我的数据访问层(dao、存储库等)中,我使用astyanax(netflix的java库)及其实体持久器将对象保存到cassandra列族中 下面是我的cassandra/astyanax支持的DAO的一些示例代码(是的,我知道我需要做一些更大规模的工作,但我仍在学习=) 在阅读了这篇冗长的描述之后,我基本上想知道,当java在字段上执行getDeclaredAnnotations()时,为

所以我的困境是:我有一个域模型,在scala中有一堆case类,比如
User
Organization
。在我的数据访问层(dao、存储库等)中,我使用astyanax(netflix的java库)及其实体持久器将对象保存到cassandra列族中

下面是我的cassandra/astyanax支持的DAO的一些示例代码(是的,我知道我需要做一些更大规模的工作,但我仍在学习=)

在阅读了这篇冗长的描述之后,我基本上想知道,当java在
字段上执行
getDeclaredAnnotations()
时,为什么参数列表中带注释的VAL不起作用,我不想返回并重构所有内容,这样我就可以使用persister,这使得保存实体变得非常简单(即
manager.put(entity)
)。如果我想继续使用case类,这样我就可以使用scalaz提供的更不可变风格的scala和
Lens
,那么我必须更新DAO并手动执行所有持久化操作,这真的会浪费时间

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

场景1-案例类别

Astyanax无法在
val

场景3-案例类或块内定义val的类

这工作得很好,因为它将
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 }
我遇到了一个类似的问题,在我的构造函数的字段中从来没有考虑到我的注释。事实上,我使用了SpringData,不可能直接在字段上映射注释(如
@index

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

object FixedScalaAnnotations {
  type Id = com.packagecontainingid.Id @field //replace by the right package
  type Column = com.packagecontainingcolumn.Column @field
}
然后在case类中导入它,并使用它而不是原始的:

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的相关文章:

@Mik378在处理JPA注释方面提供了很大的帮助,这似乎适用于使用Hibernate之类的东西的人。然而,在我的例子中,我使用的是Astyanax,这可能只是它的一个细微差别,所以根据我从@Mike378上面学到的知识,我将发布对我有效的解决方案

重要提示:当
IdBaseEntity
是一个抽象类或类时,我无法获得任何工作

解决方案:我必须让IDBASE实体成为一种特质,一切都很好

这是层次结构

BaseEntity.scala

import java.util.Date
性状基实体{
val createdOn:选项[日期]=无
val modifiedOn:选项[日期]=无
}
IdBaseEntity.scala


trait idbase实体[T所以我尝试了好几个小时,尝试了你的建议的许多排列,但都不起作用。当组织不扩展任何其他类时,它工作得很好。一旦我用抽象类或常规类引入继承,它就拒绝找到@Id注释。所以我继续将IdBaseEntity作为一个特性,而一切都很好t、 我想这很好?无论如何,不要误会,但我爱你!感谢你在这方面的教育。如果你碰巧知道为什么继承课程不起作用,我很想知道。再次感谢!我会添加对我有效的Astyanax,以防其他人遇到同样的问题,但我会接受你的答案,因为我知道从我在你发送给我的链接中读到的内容来看,t似乎起作用了。你正在处理
val
和继承。也许,我只是说也许,你暴露在这个微妙的scala规则下:。如果我是你,我会尝试两种方法:重新声明你的父母为
abstract
,并尝试处理
var
lazy val
>
id
字段只是为了看看这个规则是否与您的工作无关。另一种方法:只需将
@id
注释声明到抽象类的
val id
字段,而不是在
组织
类中声明。因此我尝试了一些方法。父类中的@id由于astyanax限制而不起作用,但是有一个pull请求可以解决这个问题。我确实发现我是个笨蛋。当我说抽象类不起作用时,是因为我从案例类组织传递了extends IdBaseEntity[UUID](id)。如果我只是离开它,它将扩展IdBaseEntity[UUID]然后一切都像一个符咒一样工作。所以我可以用更干净的默认参数列表语法而不是trait保留抽象类定义。我从这个问题中学到了很多。谢谢! 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 }
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)