Java 没有 id 的 JPA 实体

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3820897/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-14 05:29:07  来源:igfitidea点击:

JPA entity without id

javahibernatejpa

提问by mikhail

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. Is it possible to create JPA (Hibernate) entities that will work with database schema like this?

我知道 JPA 实体必须有一个主键,但由于我无法控制的原因,我无法更改数据库架构。是否可以创建与这样的数据库模式一起使用的 JPA(休眠)实体?

采纳答案by axtavt

I guess your entity_propertyhas a composite key (entity_id, name)where entity_idis a foreign key to entity. If so, you can map it as follows:

我猜你entity_property有一个复合键(entity_id, name),其中entity_id是一个外键entity。如果是这样,您可以按如下方式映射它:

@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; 

    ...
}

回答by Bozho

I guess you can use @CollectionOfElements(for hibernate/jpa 1) / @ElementCollection(jpa 2) to map a collection of "entity properties" to a Listin entity.

我想您可以使用@CollectionOfElements(对于 hibernate/jpa 1)/ @ElementCollection(jpa 2)将“实体属性”集合映射到Listin entity

You can create the EntityPropertytype and annotate it with @Embeddable

您可以创建EntityProperty类型并注释它@Embeddable

回答by Qwerky

If there is a one to one mapping between entity and entity_property you can use entity_id as the identifier.

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

回答by Pascal Thivent

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 Iddefined. But a JPA Iddoes 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定义。但是 JPAId不一定要映射到表主键上(并且 JPA 可以以某种方式处理没有主键或唯一约束的表)。

Is it possible to create JPA (Hibernate) entities that will be work with database structure like this?

是否可以创建可以使用这样的数据库结构的 JPA(休眠)实体?

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 Idin JPA.

如果您在表中有一列或一组列具有唯一值,您可以使用这组唯一的列作为您Id在 JPA 中的列。

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.

回答by Gilberto

See the Java Persistencebook: 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. 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. The JPA Iddoes not always have to match the database table primary key constraint, nor is a primary key or a unique constraint required.

If your table truly has no unique columns, then use all of the columns as the 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. 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. Make the object an Embeddableobject, embeddable objects do not have ids. You will need a Entitythat contains this Embeddableto persist and query it.

有时您的对象或表没有主键。在这种情况下,最好的解决方案通常是将生成的 id 添加到对象和表中。如果您没有此选项,有时表中会有一列或一组列构成唯一值。您可以使用这组独特的列作为 JPA 中的 ID。JPAId并不总是必须匹配数据库表主键约束,也不需要主键或唯一约束。

如果您的表确实没有唯一列,则使用所有列作为 id。通常,当发生这种情况时,数据是只读的,因此即使表允许具有相同值的重复行,对象无论如何都是相同的,因此 JPA 认为它们是同一个对象并不重要。允许更新和删除的问题在于无法唯一标识对象的行,因此所有匹配的行都将被更新或删除。

如果您的对象没有 id,但它的表有,这很好。使对象成为Embeddable对象,可嵌入的对象没有 id。您将需要一个Entity包含它的Embeddable来持久化和查询它。