为什么赢了';astyanax(java)能识别scala案例类参数列表中的@Id注释值吗?
所以我的困境是:我有一个域模型,在scala中有一堆case类,比如为什么赢了';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()时,为
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)