JPA - 为每个外键生成序列ID(非唯一)并生成复合键

时间:2017-09-26 02:43:50

标签: java postgresql scala jpa spring-data-jpa

场景:我的postgres db中有两个名为Document和Element的表。它们之间的关系是一对多的(一个文档有很多元素)。因此元素表具有文档id的外键。现在我需要从每个文档id的初始值开始有一个元素id的序列。

例如:

e_id | d_id
------------
 1   |   x
 2   |   x
 3   |   x
 1   |   y
 2   |   y
 3   |   y

有了这个之后,元素与另一个名为Labeled Element的表之间存在下一级关系,该表具有复合键(document_id,element_id)和labeler_id的复合键。

问题:

  1. 如何生成序列以从每个文档ID的初始值开始?

  2. 如何在标签表中显示复合键的JPA映射。具体哪个字段我也映射了文档ID?

  3. 以下是为方便起见的模型(在Scala中):

    元素

    @Embeddable
    class CompositeKey extends Serializable {
    
      @BeanProperty
      @Column(name = "id", nullable = false)
      var id : Long = _
    
      @BeanProperty
      @Column(name = "document_id", nullable = false)
      var documentId : UUID = _
    
      def this(id: Long, documentId: UUID) = {
        this()
        this.id = id
        this.documentId = documentId
      }
    }
    
    @Entity
    @DynamicUpdate
    @Table(name = "element")
    class Element {
    
      @EmbeddedId
      @BeanProperty
      @GeneratedValue(strategy = GenerationType.SEQUENCE)
      var id: CompositeKey = _
    
      @MapsId("documentId")
      @BeanProperty
      @JoinColumn(name = "document_id", referencedColumnName = "id")
      @ManyToOne(fetch = FetchType.LAZY)
      var document: Document = _
    

    LabeledElement

    @Embeddable
    class LabeledElementKey extends Serializable {
      @BeanProperty
      @Column(name = "document_id", nullable = false)
      var documentId : UUID = _
    
      @BeanProperty
      @Column(name = "labeler_id", nullable = false)
      var labelerId : Long = _
    
      @BeanProperty
      @Column(name = "element_id", nullable = false)
      var elementId : Long = _
    
      def this(documentId : UUID, labelerId : Long, elementId : Long) = {
        this()
        this.documentId = documentId
        this.labelerId = labelerId
        this.elementId = elementId
      }
    }
    
    @Entity
    @Table(name = "labeled_element")
    class LabeledElement {
      @EmbeddedId
      @BeanProperty
      @Column(unique = true)
      var id : LabeledElementKey = _
    
      @MapsId("labelerId")
      @JoinColumn(name = "labeler_id", referencedColumnName = "id")
      @ManyToOne(fetch = FetchType.LAZY)
      var labeler: Labeler = _
    
      @MapsId("elementId")
      @JoinColumns(Array(
        new JoinColumn (name = "element_id", referencedColumnName = "id"),
        new JoinColumn (name = "document_id", referencedColumnName = "document_id")
      ))
      @ManyToOne(fetch = FetchType.LAZY)
      var element: Element = _
    // goes on
    

    以现在的方式,我收到以下错误:

    org.hibernate.AnnotationException: No identifier specified for entity: model.Element
    

    您的努力将不胜感激。谢谢!

1 个答案:

答案 0 :(得分:0)

您的Element类有一个注释@Embeddable而不是@EmbeddedId