没有ID的JPA实体

2w2cym1i  于 2022-11-14  发布在  其他
关注(0)|答案(5)|浏览(438)

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

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)实体来使用数据库模式?

ig9co6j1

ig9co6j11#

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

    ...
}
dnph8jn4

dnph8jn42#

我知道JPA实体必须有主键,但由于我无法控制的原因,我不能更改数据库结构。
更准确地说,JPA实体必须定义一些Id,但是JPA Id不一定要Map到表主键上(JPA可以处理没有主键或唯一约束的表)。
有没有可能创建JPA(Hibernate)实体来处理这样的数据库结构?
如果表中的一列或一组列具有唯一值,则可以将这组唯一的列用作JPA中的Id
如果您的表根本没有唯一列,则可以将所有列用作Id
如果你的表有一些id,但你的实体没有,把它设为Embeddable

vmjh9lq9

vmjh9lq93#

请参阅 *Java持久性 * 一书:Identity and Sequencing
与您的问题相关的部分是“无主键”部分:
有时您的对象或表没有主键。在这种情况下,最好的解决方案通常是为对象和表添加一个生成的id。如果您没有此选项,有时表中有一列或一组列组成了一个唯一的值,您可以在JPA中使用这组唯一的列作为您的id。JPA Id不必始终与数据库表主键约束相匹配,也不需要主键或唯一约束。
如果您的表确实没有唯一的列,则使用所有列作为id。通常,当出现这种情况时,数据是只读的,因此即使表允许具有相同值的重复行,对象也将是相同的,因此JPA认为它们是相同的对象并不重要。允许更新和删除的问题是没有办法唯一地标识对象的行,因此所有匹配的行都将被更新或删除。
如果你的对象没有id,但它的表有,这是可以的。使对象成为Embeddable对象,可嵌入的对象没有id。你需要一个包含这个EmbeddableEntity来持久化和查询它。

mnemlml8

mnemlml84#

我想您可以使用@CollectionOfElements(针对hib/jpa 1)/@ElementCollection(jpa 2)将一组“实体属性”Map到entity中的List
您可以创建EntityProperty类型并使用@Embeddable对其进行注解

nnt7mjpx

nnt7mjpx5#

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

相关问题