当前位置: 首页 > 知识库问答 >
问题:

从@MappedSuperClass创建具有@id复合主键的JPA实体

苏俊友
2023-03-14

我有一个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));
        }
    }
}

共有1个答案

子车修平
2023-03-14

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

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

 类似资料:
  • 我有一个实体,它的复合主键由两个字段组成,其中一个也是复合外键的一部分。 背景:我有实体<代码>人员 、<代码>区域 和<代码>会话 。 与具有多对多关系,使用称为“和实体。 所以,我有,主键为(,)。本身是的外键。 也有一个字段。我希望(,)是的复合外键。 我的PersonSession代码: } 这看起来不错,它在数据库中创建了所有正确的关系。当我尝试插入个性化会话对象时,问题就出现了——ar

  • 我在oracle数据库中有一个包含客户数据的表。以下是一个简化的定义: 此表的主键是。 该表有许多行,其中为空。在数据库级别,没有问题,但是当我试图通过JPA实体访问这些行时,会导致一些问题: 1:使用

  • 我有3分贝实体。产品-id,名称。/产品订单-id,日期。/Orders OrderDetail-OrderID,productId,Price。订单/{orderId}/orderDetails 谢了!

  • 问题内容: 我的JPA模型中有以下类(省略了getters,setters和无关字段): 我需要定义一个类,使得当从所述类生成DDL时,相应的表的主键被由密钥和。我尝试了以下方法: 但这会为表生成以下内容: 请注意,和都是可为空的,当我尝试将DDL加载到SQL Server时会导致以下错误 无法在表“ PRICE”中的可为空的列上定义PRIMARY KEY约束 我不明白为什么这些可以为空,因为在域

  • EmbeddedId或IdClass注释用于表示复合主键。如何在没有(EmbeddedId或IdClass)的情况下使用复合主键? 如果可以在没有(EmbeddedId或IdClass)的情况下使用复合主键,那么如何使用EntityManager.find(Entity Class,Object primaryKey)方法在复合主键(Multiple primaryKey)的情况下查找实体(因为没

  • 本文向大家介绍Spring Data Jpa 复合主键的实现,包括了Spring Data Jpa 复合主键的实现的使用技巧和注意事项,需要的朋友参考一下 前言 这次大创有个需求,在数据库建表时发现,user表与project表的关系表 user_project的主键为复合主键: 在网上看了几篇博客,以及在spring boot干货群咨询(感谢夜升额耐心解答)过后总算是做出来了。这里做个总结,方便