我们在使用JPA对历史问题处理时,会涉及到组合主键的处理。处理的思路如下:

  • 使用@Embeddabel定义一个组合组键ID
  • ID实现SErializable接口
  • 声明一个protected的构造方法
  • 声明带有复合主键属性的构造方法
  • 重写equals和hasCode方法

比如,我有一个使用studentId和courseId两个字段做为主键的复习主键表。

clipboard.png

定义代码如下:

package com.mengyunzhi.english.entity;

import javax.persistence.Embeddable;
import javax.persistence.EmbeddedId;
import javax.persistence.Entity;
import javax.persistence.Table;
import java.io.Serializable;
import java.util.Objects;

/**
 * 学生单词学习节点
 * 记录学生学习某门课的单词进度
 * panjie
 */
@Entity
@Table(name = "english_student_word_study_node")
public class StudentWordStudyNode {
    @EmbeddedId
    private Id id;
    private Short maxIndex;

    protected StudentWordStudyNode() {
    }

    public StudentWordStudyNode(Id id) {
        this.id = id;
    }

    public Id getId() {
        return id;
    }

    public void setId(Id id) {
        this.id = id;
    }

    public java.lang.Short getMaxIndex() {
        return maxIndex;
    }

    public void setMaxIndex(java.lang.Short maxIndex) {
        this.maxIndex = maxIndex;
    }

    @Embeddable
    static public class Id implements Serializable {
        protected Integer studentId;
        protected Integer courseId;

        protected Id() {
        }

        public Id(Integer studentId, Integer courseId) {
            this.studentId = studentId;
            this.courseId = courseId;
        }

        public Integer getStudentId() {
            return studentId;
        }

        public void setStudentId(Integer studentId) {
            this.studentId = studentId;
        }

        public Integer getCourseId() {
            return courseId;
        }

        public void setCourseId(Integer courseId) {
            this.courseId = courseId;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) return true;
            if (!(o instanceof Id)) return false;
            Id id = (Id) o;
            return Objects.equals(studentId, id.studentId) &&
                    Objects.equals(courseId, id.courseId);
        }

        @Override
        public int hashCode() {
            return Objects.hash(studentId, courseId);
        }
    }
}

注意:内部类ID的static不能少。这是由于:我们将主键ID声明为了内部类,而其做为复合组件出现,是需要直接暴露无参的构造函数的,否则将出现:No default constructor for entity


潘杰
3.1k 声望238 粉丝

引用和评论

0 条评论