首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >使用泛型Id扩展基实体的实体的Id映射

使用泛型Id扩展基实体的实体的Id映射
EN

Stack Overflow用户
提问于 2015-12-14 16:21:58
回答 4查看 4.4K关注 0票数 2

:JPA2.1,扩展具有通用id的基实体的实体。

具有通用id的Entity的接口:

代码语言:javascript
运行
复制
public interface Entity<ID extends Serializable> extends Serializable {
    public ID getId();
    public void setId(ID id);
}

基本实现(抽象)定义了一些附加的公共属性:

代码语言:javascript
运行
复制
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

代码语言:javascript
运行
复制
public class Person extends BaseEntity<UUID> {

    public Person() {
        setId(UUID.randomUUID());
    }
    // attributes, getters and setters
}

Address,其ids为Long,由序列生成:

代码语言:javascript
运行
复制
public class Address extends BaseEntity<Long> {
    // attributes, getters and setters
}

O/R-测绘:

代码语言:javascript
运行
复制
<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)对PersonAddress的id属性发出警告

“属性”"id“是继承的;引用orm.xml中继承的属性可能不是所有持久性提供程序都支持的”

在运行测试时,我得到以下异常:

代码语言:javascript
运行
复制
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,但希望在那里使用序列)。

任何帮助/暗示都是非常感谢的,谢谢。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2015-12-15 22:16:24

通过拆分成两个部分解决了这个问题:一个是id (未映射),另一个是元数据(创建/修改时间戳和版本):

代码语言:javascript
运行
复制
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.

代码语言:javascript
运行
复制
<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>

..。允许PersonAddress定义他们喜欢的任何Id (属性名为"id",映射到具有生成值的任意列)。

对于JPA要识别的泛型ID的实际类型,必须重写getId()方法以将结果缩小到实际类型:

代码语言:javascript
运行
复制
public class Address extends BaseEntity<Long> {
    // ...
    @Override
    public Long getId() {
        return super.getId();
    }
    // ...
}
票数 1
EN

Stack Overflow用户

发布于 2015-12-14 16:31:25

从JPA的角度来看,您不能以描述的方式定义两个标识策略。

一个不同的解决方案可能是拥有一个BaseEntity,这个子类具有不同的身份策略,比如IdentityBaseEntitySelfIdentifyingBaseEntity

从这里开始,您的子类将选择它希望子类的标识父类。

票数 2
EN

Stack Overflow用户

发布于 2015-12-14 17:03:37

根据JPA 2.1.专门性

11.1.4 AttributeOverride注解 AttributeOverride注释用于覆盖基本(显式或默认)属性或字段或Id、属性或字段的映射。..。 12.2.3.15关联-重写关联-重写子元素是对实体上的任何AssociationOverride或AssociationOverrides注释的添加。它为相同的属性名重写任何AssociationOverride元素。如果存在关联重写子元素,且未显式指定该关联重写子元素的属性或子元素,则应用它们的默认值。

所以,你应该试试这样的方法:

代码语言:javascript
运行
复制
<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>

代码语言:javascript
运行
复制
<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手册中的示例。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/34271833

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档