:JPA2.1,扩展具有通用id的基实体的实体。
具有通用id的Entity
的接口:
public interface Entity<ID extends Serializable> extends Serializable {
public ID getId();
public void setId(ID id);
}
基本实现(抽象)定义了一些附加的公共属性:
public abstract class BaseEntity<ID extends Serializable> implements Entity<ID> {
private LocalDateTime creationTimestamp;
private LocalDateTime lastModificationTimestamp;
private Long version;
private ID id;
// getters and setters
}
一些具体实体:Person
,其id是在持久化之前分配的UUID
:
public class Person extends BaseEntity<UUID> {
public Person() {
setId(UUID.randomUUID());
}
// attributes, getters and setters
}
和Address
,其ids为Long
,由序列生成:
public class Address extends BaseEntity<Long> {
// attributes, getters and setters
}
O/R-测绘:
<mapped-superclass class="idx.evaluation.jpa.hibernate.framework.BaseEntity">
<attributes>
<basic name="creationTimestamp">
<column name="created" updatable="false" />
</basic>
<basic name="lastModificationTimestamp">
<column name="last_modified" />
</basic>
<version name="version">
<column name="version" />
</version>
</attributes>
</mapped-superclass>
<entity class="idx.evaluation.jpa.hibernate.model.Person">
<table name="person" />
<attributes>
<id name="id">
<column name="id" nullable="false" unique="true" />
</id>
<!-- more attributes -->
</attributes>
</entity>
<entity class="idx.evaluation.jpa.hibernate.model.Address">
<table name="address" />
<attributes>
<id name="id">
<column name="id" nullable="false" unique="true" />
<generated-value strategy="SEQUENCE" generator="id_sequence" />
</id>
<!-- more attributes -->
</attributes>
</entity>
My (Eclipse4.5)对Person
和Address
的id属性发出警告
“属性”"id“是继承的;引用orm.xml中继承的属性可能不是所有持久性提供程序都支持的”
在运行测试时,我得到以下异常:
javax.persistence.PersistenceException: Unable to build entity manager factory
...
Caused by: org.hibernate.AnnotationException:
No identifier specified for entity: idx.evaluation.jpa.hibernate.model.Person
问题:我如何实现这样的映射,其中基类定义了一个泛型Id属性,但是每个子类的Id映射/生成方式不同?我再次尝试在id上使用attribute-override
,这对Person
有效,但对Address
无效(因为我不能为覆盖指定generated-value
,但希望在那里使用序列)。
任何帮助/暗示都是非常感谢的,谢谢。
发布于 2015-12-15 22:16:24
通过将拆分成两个部分解决了这个问题:一个是id (未映射),另一个是元数据(创建/修改时间戳和版本):
public abstract class EntityMetadata {
private LocalDateTime creationTimestamp;
private LocalDateTime lastModificationTimestamp;
private Long version;
// setters and getters
}
public abstract class BaseEntity<ID extends Serializable>
extends EntityMetadata implements Entity<ID> {
private ID id;
// setters and getters
}
EntityMetadata映射没有定义Id.
<mapped-superclass class="idx.evaluation.jpa.hibernate.framework.entity.EntityMetadata">
<attributes>
<basic name="creationTimestamp">
<column name="created" updatable="false" />
</basic>
<basic name="lastModificationTimestamp">
<column name="last_modified" />
</basic>
<version name="version">
<column name="version" />
</version>
</attributes>
</mapped-superclass>
..。允许Person
和Address
定义他们喜欢的任何Id (属性名为"id"
,映射到具有生成值的任意列)。
对于JPA要识别的泛型ID的实际类型,必须重写getId()
方法以将结果缩小到实际类型:
public class Address extends BaseEntity<Long> {
// ...
@Override
public Long getId() {
return super.getId();
}
// ...
}
发布于 2015-12-14 16:31:25
从JPA的角度来看,您不能以描述的方式定义两个标识策略。
一个不同的解决方案可能是拥有一个BaseEntity
,这个子类具有不同的身份策略,比如IdentityBaseEntity
和SelfIdentifyingBaseEntity
。
从这里开始,您的子类将选择它希望子类的标识父类。
发布于 2015-12-14 17:03:37
根据JPA 2.1.专门性
11.1.4 AttributeOverride注解 AttributeOverride注释用于覆盖基本(显式或默认)属性或字段或Id、属性或字段的映射。..。 12.2.3.15关联-重写关联-重写子元素是对实体上的任何AssociationOverride或AssociationOverrides注释的添加。它为相同的属性名重写任何AssociationOverride元素。如果存在关联重写子元素,且未显式指定该关联重写子元素的属性或子元素,则应用它们的默认值。
所以,你应该试试这样的方法:
<entity class="idx.evaluation.jpa.hibernate.model.Person">
<table name="person" />
<attribute-override name="id">
<column name="id" nullable="false" unique="true" />
</attribute-override>
</entity>
或
<entity class="idx.evaluation.jpa.hibernate.model.Address">
<table name="address" />
<attribute-override name="id">
<column name="id" nullable="false" unique="true" />
</attribute-override>
<attributes>
<id name="id">
<column name="id" nullable="false" unique="true" />
<generated-value strategy="SEQUENCE" generator="id_sequence" />
</id>
<!-- more attributes -->
</attributes>
</entity>
有关更多信息,请参见hibernate手册中的这示例。
https://stackoverflow.com/questions/34271833
复制相似问题