没有id的JPA实体

mik*_*ail 48 java hibernate jpa

我有一个具有以下结构的数据库:

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

CREATE TABLE entity_property (
    entity_id SERIAL,
    name VARCHAR(255),
    value TEXT
);
Run Code Online (Sandbox Code Playgroud)

当我尝试创建一个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;
    }
}
Run Code Online (Sandbox Code Playgroud)

我得到以下异常:

org.hibernate.AnnotationException: No identifier specified for entity: package.EntityProperty
Run Code Online (Sandbox Code Playgroud)

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

axt*_*avt 46

我猜你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; 

    ...
}
Run Code Online (Sandbox Code Playgroud)

  • `EntityPropertyPK`的注释应该是`@ Embeddedable`而不是`@Embedded`? (4认同)
  • 谢谢。但是在这种情况下如何直接访问实体“名称”属性?我的 JP-QL 查询只有在通过“entity.id.name”访问“name”时才有效,但我认为这是不对的。 (2认同)

Pas*_*ent 27

我知道JPA实体必须有主键,但由于我无法控制的原因,我无法更改数据库结构.

更准确地说,JPA实体必须有一些Id定义.但是JPA Id不一定必须映射到表主键上(并且JPA可以某种方式处理没有主键或唯一约束的表).

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

如果表中有一列或一组列具有唯一值,则可以使用此唯一列集作为IdJPA中的列.

如果您的表根本没有唯一列,则可以使用所有列作为Id.

如果你的表有一些id,但你的实体没有,那就把它变成一个Embeddable.

  • 拜托,我是新来的。如何使用这个小示例将所有列用作实体中的 ID:int SIN、int age、String name、String adresse。谢谢你 (4认同)
  • “您可以使用所有列作为 Id”,但我的表需要能够将相同的行存储为单独的记录;c (3认同)

Gil*_*rto 23

请参阅Java持久性书:身份和排序

您的问题的相关部分是No Primary Key部分:

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

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

如果你的对象没有id,但它的'table',这很好.使对象成为Embeddable对象,可嵌入对象没有id.你需要一个Entity包含它的东西Embeddable来持久化并查询它.