我有一个具有以下结构的数据库:
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)实体?
答案 0 :(得分:38)
我猜你的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;
...
}
答案 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作为标识符。