繁体   English   中英

JPA(休眠):在通用@MappedSuperclass中使用@EmbeddedId时出错

[英]JPA (Hibernate): Error when using @EmbeddedId in generic @MappedSuperclass

我目前正在为旧数据库定义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]

我已经调试了这一点,发现在休眠状态下,元模型将我的所有实体都映射到相同的MappedSupperclass实例。 在应用程序启动期间,将newId()返回的@EmbeddedId设置为MappedSupperclass,从而覆盖前一个实体的ID。 因此,最后,所有实体都映射到相同的MappedSupperclass,但是MappedSupperclass仅具有最后一个实体的@EmbeddedId

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

现在我想知道我的方法是否错误,是否缺少某些东西,或者这可能是休眠问题?

使用spring boot的完整示例可在github上获得 使用mvn spring-boot:run

在我看来,这就像是休眠中的错误,因此我在休眠中的错误跟踪器中创建了一个票证。 作为一种解决方法,我现在在concreate实体类而不是抽象超类中定义ID属性(@EmbeddedId)。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM