Java 没有id的JPA实体

Java 没有id的JPA实体,java,hibernate,jpa,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_pro

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

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)实体来处理这样的数据库模式

我想您可以使用(对于hibernate/jpa 1)/(jpa 2)将“实体属性”集合映射到
实体中的
列表


您可以创建
EntityProperty
类型,并使用
@Embeddeble

对其进行注释。如果实体和实体属性之间存在一对一的映射,您可以使用实体id作为标识符。

我猜您的
实体属性有一个复合键
(实体id,名称)
其中
实体_id
实体
的外键。如果是,您可以按如下方式映射它:

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

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

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

是否可以创建JPA(Hibernate)实体来处理这样的数据库结构

如果表中有一列或一组列生成唯一值,则可以在JPA中将此唯一列集用作
Id

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

如果您的表有一些id,但您的实体没有,则将其设置为可嵌入的

请参阅Java持久性手册:

你的问题的相关部分是:

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

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

如果您的对象没有id,但其“表”有id,则可以。 使对象成为可嵌入的对象,可嵌入的对象 没有身份证。您将需要一个包含 此
可嵌入
以持久化和查询它


谢谢但在这种情况下,如何直接访问实体“name”属性?只有通过“entity.id.name”访问“name”时,我的JP-QL查询才能正常工作,但我认为这是不对的。@mikhail:如果您不喜欢使用
@EmbeddedId
,您可以使用
@IdClass
尝试另一种方法:
EntityPropertyPK
的注释应该是
@Embedded
而不是
@Embedded
?是的,
EntityPropertyPK
的注释必须是
@Embedded
,因为
@Embedded
只能应用于字段和方法。此外,class
EntityPropertyPK
必须声明为可序列化的
。在这个小示例中,如何使用实体中的所有列作为ID:int SIN、int age、String name、String address。感谢您关于
@ElementCollection
@CollectionTable
的一个很好的示例位于。另见