简体   繁体   English

没有id的JPA实体

[英]JPA entity without id

I have a database with the following structure: 我有一个具有以下结构的数据库:

CREATE TABLE entity (
    id SERIAL,
    name VARCHAR(255),
    PRIMARY KEY (id)
);

CREATE TABLE entity_property (
    entity_id SERIAL,
    name VARCHAR(255),
    value TEXT
);

When I try to create an EntityProperty class 当我尝试创建一个EntityProperty类时

@Entity
@Table(name="entity_property")
public class EntityProperty {

    private String name;
    private String value;

    @Column(name="name")
    public String getName() {
        return name;
    }
    public void setName(String name) {
        this.name = name;
    }

    @Column(name="value", nullable=true, length=255)
    public String getValue() {
        return value;
    }
    public void setValue(String value) {
        this.value = value;
    }
}

I get the following exception: 我得到以下异常:

org.hibernate.AnnotationException: No identifier specified for entity: package.EntityProperty

I know that JPA entities must have a primary key but I can't change the database schema due to reasons that are beyond my control. 我知道JPA实体必须有一个主键,但由于我无法控制的原因,我无法更改数据库模式。 Is it possible to create JPA (Hibernate) entities that will work with database schema like this? 是否可以创建可以使用这样的数据库模式的JPA(Hibernate)实体?

I guess your entity_property has a composite key (entity_id, name) where entity_id is a foreign key to entity . 我猜你的entity_property有一个复合键(entity_id, name) ,其中entity_identity的外键。 If so, you can map it as follows: 如果是这样,您可以按如下方式映射:

@Embeddable
public class EntityPropertyPK {
    @Column(name = "name")
    private String name;

    @ManyToOne
    @JoinColumn(name = "entity_id")
    private Entity entity;

    ...
}

@Entity 
@Table(name="entity_property") 
public class EntityProperty { 
    @EmbeddedId
    private EntityPropertyPK id;

    @Column(name = "value")
    private String value; 

    ...
}

I know that JPA entities must have primary key but I can't change database structure due to reasons beyond my control. 我知道JPA实体必须有主键,但由于我无法控制的原因,我无法更改数据库结构。

More precisely, a JPA entity must have some Id defined. 更准确地说,JPA实体必须定义一些Id But a JPA Id does not necessarily have to be mapped on the table primary key (and JPA can somehow deal with a table without a primary key or unique constraint). 但是JPA Id不一定必须映射到表主键上(并且JPA可以某种方式处理没有主键或唯一约束的表)。

Is it possible to create JPA (Hibernate) entities that will be work with database structure like this? 是否可以创建将使用这样的数据库结构的JPA(Hibernate)实体?

If you have a column or a set of columns in the table that makes a unique value, you can use this unique set of columns as your Id in JPA. 如果表中有一列或一组列具有唯一值,则可以使用此唯一列集作为JPA中的Id

If your table has no unique columns at all, you can use all of the columns as the Id . 如果您的表根本没有唯一列,则可以使用所有列作为Id

And if your table has some id but your entity doesn't, make it an Embeddable . 如果您的表有一些id,但您的实体没有,请将其Embeddable

See the Java Persistence book: Identity and Sequencing 请参阅Java持久性书: 身份和排序

The relevant part for your question is the No Primary Key section : 您的问题的相关部分是No Primary Key部分

Sometimes your object or table has no primary key. 有时您的对象或表没有主键。 The best solution in this case is normally to add a generated id to the object and table. 在这种情况下,最佳解决方案通常是将生成的id添加到对象和表中。 If you do not have this option, sometimes there is a column or set of columns in the table that make up a unique value. 如果您没有此选项,则有时表中会有一列或一组列构成唯一值。 You can use this unique set of columns as your id in JPA. 您可以使用此唯一列集作为JPA中的ID。 The JPA Id does not always have to match the database table primary key constraint, nor is a primary key or a unique constraint required. JPA Id并不总是必须匹配数据库表主键约束,也不需要主键或唯一约束。

If your table truly has no unique columns, then use all of the columns as the id. 如果您的表确实没有唯一列,则使用所有列作为id。 Typically when this occurs the data is read-only, so even if the table allows duplicate rows with the same values, the objects will be the same anyway, so it does not matter that JPA thinks they are the same object. 通常,当发生这种情况时,数据是只读的,因此即使表允许具有相同值的重复行,对象仍然是相同的,因此JPA认为它们是同一个对象并不重要。 The issue with allowing updates and deletes is that there is no way to uniquely identify the object's row, so all of the matching rows will be updated or deleted. 允许更新和删除的问题是无法唯一标识对象的行,因此将更新或删除所有匹配的行。

If your object does not have an id, but its' table does, this is fine. 如果你的对象没有id,但它的'table',这很好。 Make the object an Embeddable object, embeddable objects do not have ids. 使对象成为Embeddable对象,可嵌入对象没有id。 You will need a Entity that contains this Embeddable to persist and query it. 您将需要一个包含此EmbeddableEntity来持久化并查询它。

I guess you can use @CollectionOfElements (for hibernate/jpa 1) / @ElementCollection (jpa 2) to map a collection of "entity properties" to a List in entity . 我想你可以使用@CollectionOfElements (对Hibernate / JPA 1)/ @ElementCollection (JPA 2)的“实体性”的集合映射到List中的entity

You can create the EntityProperty type and annotate it with @Embeddable 您可以创建EntityProperty类型并使用@Embeddable注释它

如果entity和entity_property之间存在一对一映射,则可以使用entity_id作为标识符。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM