加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 编程开发 > Java > 正文

java – JPA(Hibernate):在泛型@MappedSuperclass中使用@Embedd

发布时间:2020-12-15 02:20:06 所属栏目:Java 来源:网络整理
导读:我目前正在为遗留数据库定义JPA实体(许多复合键,但也包括单列键).我创建了以下实体超类: @MappedSuperclasspublic abstract class AbstractEntityID extends Serializable { public abstract ID getId(); public abstract void setId(ID id);} 然后是复合键
我目前正在为遗留数据库定义JPA实体(许多复合键,但也包括单列键).我创建了以下实体超类:

@MappedSuperclass
public abstract class AbstractEntity<ID extends Serializable> {
    public abstract ID getId();
    public abstract void setId(ID id);
}

然后是复合键的超类(以及长主键的超类,此处未列出):

@MappedSuperclass
public abstract class AbstractEmbeddedIdEntity<ID extends Serializable> extends AbstractEntity<ID> {
    @EmbeddedId
    private ID id;

    public AbstractEmbeddedIdEntity() {
        id = newId();
    }

    @Override
    public ID getId() {
        return id;
    }

    @Override
    public void setId(ID id) {
        this.id = id;
    }

    protected abstract ID newId();
}

最后这样的具体实体:

@Entity
@Table(name = "firstEntity")
public class FirstEntity extends AbstractEmbeddedIdEntity<FirstEntityId> {

    public FirstEntity() {
    }

    @Embeddable
    public static class FirstEntityId implements Serializable {
        @Column(name = "firstId")
        private String firstId;

        public FirstEntityId() {
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == this) {
                return true;
            }
            if (!(obj instanceof FirstEntityId)) {
                return false;
            }
            FirstEntityId other = (FirstEntityId) obj;
            return 
                    Objects.equals(firstId,other.firstId);
        }

        @Override
        public int hashCode() {
            return Objects.hash(firstId);
        }
    }

    @Override
    protected FirstEntityId newId() {
        return new FirstEntityId();
    }
}

现在的问题是,如果我有这样的多个实体并尝试访问实体的ID属性(当前使用Spring Boot,例如findByIdFirstId(String firstId)),则抛出异常:

java.lang.IllegalArgumentException: Unable to locate Attribute  with the the given name [firstId] on this ManagedType [unknown]

我调试了这个并发现在hibernate中,元模型将我的所有实体映射到相同的MappedSupperclass实例.在应用程序启动期间,newId()返回的@EmbeddedId设置为MappedSupperclass,覆盖前一个实体的ID.所以最后,所有实体都映射到相同的MappedSupperclass,但MappedSupperclass只有最后一个实体的@EmbeddedId.

在上面的示例中,访问ID属性失败,因为最后一个实体的@EmbeddedId没有名为“firstId”的属性(它已被最后一个实体的ID属性覆盖).

现在我想知道我的方法是否错误,如果我遗漏了什么或者这可能是hibernate的问题?

使用spring boot available on github的完整示例.使用mvn spring-boot:run运行.

解决方法

这看起来像是一个hibernate中的bug,因此我在 hibernate bug tracker中创建了一个票证. 作为一种解决方法,我现在在concreate实体类中定义ID属性(@EmbeddedId)而不是抽象超类.

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读