Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用@MappedSuperclass中的@Id复合主键创建JPA实体_Jpa_Eclipselink - Fatal编程技术网

使用@MappedSuperclass中的@Id复合主键创建JPA实体

使用@MappedSuperclass中的@Id复合主键创建JPA实体,jpa,eclipselink,Jpa,Eclipselink,我有一个JPA实体的类层次结构,基类是定义了一个ID的MappedSuperclass。我试图在子类中使用复合键,但这似乎不起作用 我的代码如下所示 @MappedSuperclass public class BaseEntity implements Serializable { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) @Basic(optional = false) @Col

我有一个JPA实体的类层次结构,基类是定义了一个ID的MappedSuperclass。我试图在子类中使用复合键,但这似乎不起作用

我的代码如下所示

@MappedSuperclass
public class BaseEntity implements Serializable {
    @Id  
    @GeneratedValue(strategy = GenerationType.IDENTITY)  
    @Basic(optional = false)  
    @Column(name = "id")  
    protected Long id;  

    public Long getId() {
        return id;
    }

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


@Entity
@EntityListeners(EntityBaseListener.class)
@Inheritance(strategy=InheritanceType.JOINED)  
@Table(name = "catalog_entity")  
public class BaseCatalogEntity extends BaseEntity {

    @Column(name = "created_at", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date createdAt;

    @Column(name = "updated_at", nullable = false)
    @Temporal(TemporalType.TIMESTAMP)
    private Date updatedAt;


    public void setCreatedAt(Date date)
    {
        createdAt = date;
    }

    public void setUpdatedAt(Date date)
    {
        updatedAt = date;
    }

    public Date getCreatedAt() {
        return createdAt;
    }

    public Date getUpdatedAt() {
        return updatedAt;
    }

}


@Entity
@Table(schema = "student_catalog")
@IdClass(value = StudentCatalog.StudentCatalogPK.class)
public class StudentCatalog extends BaseCatalogEntity {

    @Id
    @Column(name = "name", nullable = false, length = 100)
    private String name;

    @Id
    @Column(name = "version", nullable = false)
    private Integer version;

    @Column(name = "description" , length = 255)
    private String description; 

    @Column(name = "vendor" , length = 50)
    private String vendor; 

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public Integer getVersion() {
        return version;
    }

    public void setVersion(Integer version) {
        this.version = version;
    }

    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public String getVendor() {
        return vendor;
    }

    public void setVendor(String vendor) {
        this.vendor = vendor;
    }

    public static class StudentCatalogPK implements Serializable {

        private Long id;
        private String name;
        private Integer version;

        public Long getId() {
            return id;
        }

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

        public String getName() {
            return name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public Integer getVersion() {
            return version;
        }

        public void setVersion(Integer version) {
            this.version = version;
        }

        @Override
        public boolean equals(Object obj) {
            boolean result = false;
            if(obj != null && (obj instanceof StudentCatalogPK)) {
                StudentCatalogPK other = (StudentCatalogPK)obj;
                result = (Objects.equals(this.id, other.id) && Objects.equals(this.name, other.name) &&
                        Objects.equals(this.version, other.version));
            }
            return result;
        }

        @Override
        public int hashCode() {
            return (27780 + (this.id != null ? this.id.hashCode() : 0) +
                           (this.version != null ? this.version.hashCode() : 0) +
                           (this.name != null ? this.name.hashCode() : 0));
        }
    }
}
我得到以下例外情况:

异常说明:组合主键规范无效。主键类[com.example.jpa.StudentCatalog$StudentCatalogPK]和实体bean类[class com.example.jpa.StudentCatalog]中的主键字段或属性的名称必须对应,并且它们的类型必须相同。此外,请确保已为XML中的相应属性指定了ID元素和/或在实体类的相应字段或属性上指定了@ID


我正在使用Eclipselink 2.5.1。有没有一种方法可以在不更改BaseEntity和BaseCalogEntity类的情况下使其工作?

在JPA中,在子类中重新定义id是不合法的。这将导致表映射和多态查询中的歧义


当业务密钥用于DB标识时,扩展超类中定义的密钥是一个常见问题。我建议仅使用代理密钥(like)作为DB标识,使用业务密钥作为实例标识。

在以下条件下:

  • 您的基本实体应该使用
    表每类继承(正如我所看到的)
  • 您的基本实体(复合键)键的类型与您希望在派生类中拥有的键的类型相同(因此还应该有String和Integer的复合键)
您可以在类声明下使用
@AttributeOverride
注释,从中删除
@Id
字段:

@AttributeOverride(name = "id", column = @Column(name = "NAME"))

因此,可以更改派生实体表中的列名,这是您所能达到的最大值。

使用@MappedSuperClass时,建议将BaseEntity类设置为抽象类,然后从其他实体类扩展基类

更干净的方法—牢记继承并设计应用程序