没有id的JPA实体

时间:2010-09-29 10:53:36

标签: 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
);

当我尝试创建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;
    }
}

我得到以下异常:

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

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

5 个答案:

答案 0 :(得分:38)

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

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

    ...
}

答案 1 :(得分:24)

  

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

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

  

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

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

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

如果您的表有一些ID,但您的实体没有,请将其设为Embeddable

答案 2 :(得分:18)

请参阅 Java Persistence 一书:Identity and Sequencing

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

  

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

     

如果您的表确实没有唯一列,则使用所有列   作为身份证。通常,当发生这种情况时,数据是只读的,甚至是偶数   如果表允许具有相同值的重复行,则为对象   无论如何都是一样的,所以JPA认为他们并不重要   是同一个对象。允许更新和删除的问题是   没有办法唯一地识别对象的行,所以全部   匹配的行将被更新或删除。

     

如果你的对象没有id,但它的'table'没有id,这很好。   使对象成为Embeddable对象,可嵌入对象   没有ids。您需要一个包含的Entity   这个Embeddable可以保留并查询它。

答案 3 :(得分:3)

我猜您可以使用@CollectionOfElements(对于hibernate / jpa 1)/ @ElementCollection(jpa 2)将“实体属性”的集合映射到{{1}中的List }}

您可以创建entity类型并使用EntityProperty

对其进行注释

答案 4 :(得分:1)

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