簡體   English   中英

為什么astyanax(java)不會在我的scala案例類參數列表中識別我的@Id注釋值?

[英]Why won't astyanax (java) recognize my @Id annotated values in my scala case class parameter list?

所以這就是我的困境:我有一個域模型,其中包含一些scala中的案例類,例如UserOrganization 在我的數據訪問層(dao,存儲庫等)中,我使用的是astyanax(來自netflix的java庫),它的實體持久化將對象保存到cassandra列族。

這是我的cassandra / astyanax支持的DAO的一些示例代碼(是的,我知道我需要做更多的scala-ish,但我還在學習=))

在閱讀了這篇冗長的描述之后,我基本上都在尋找為什么當Java在Field上執行getDeclaredAnnotations()時,param列表中的注釋val將無法工作我不想回去並重構所有內容以便我可以使用persister使得保存實體非常簡單(即manager.put(entity) )。 如果我想繼續使用case類,那么我可以使用更多不可變的樣式scala和scalaz中的Lens ,我將不得不更新DAO並手動執行所有持久化操作,這可以真正消磨時間。

所以,如果有人知道我沒有看到的東西,請告訴我! 提前感謝您花時間閱讀本文。

場景1 - 案例類

Astyanax未能在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)

場景2 - 具有伴隨對象的類或沒有伴隨對象的類

Astyanax未能在val上獲取@Id注釋

@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類或類

這樣可以正常工作,因為它選擇帶有@Id注釋的theId ,但是我不想這樣做,因為IdBaseEntity已經定義並且id val並且IdBaseEntity了繼承的整個目的並且能夠將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 
}

我遇到了一個類似的問題,我的注釋從未在構造函數的字段中考慮過。 實際上,我使用了SpringData,並且不可能直接在一個字段上映射注釋(如@Indexed )。

要在case類的構造函數中啟用注釋,首先應創建此類:

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/

@ Mik378在處理JPA注釋方面提供了很大的幫助,這對於像Hibernate這樣的人來說似乎很有用。 然而,在我的情況下,我正在使用Astyanax,它可能只是它的一個細微差別所以我將發布解決方案,對我來說,我從上面的@ Mike378學到了什么。

重要提示:當IdBaseEntity是一個抽象類或類時,我無法工作

解決方案:我不得不讓IdBaseEntity成為一個特質而且一切都很好

這是層次結構

BaseEntity.scala

import java.util.Date

trait BaseEntity {
  val createdOn: Option[Date] = None
  val modifiedOn: Option[Date] = None
}

IdBaseEntity.scala

trait IdBaseEntity[T <: java.io.Serializable] extends BaseEntity {
  val id: Option[T] = None
}

FixedScalaAnnotations.scala

import scala.annotation.meta.field

object FixedScalaAnnotations {
  type Id = javax.persistence.Id @field
  type Column = javax.persistence.Column @field
}

Organization.scala

import java.util.{Date, UUID}
import FixedScalaAnnotations._
import javax.persistence.Entity

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM