java - JPA( hibernate ): Error when using @EmbeddedId in generic @MappedSuperclass

标签 java spring hibernate jpa

我目前正在为遗留数据库定义 JPA 实体(很多复合键,但也有单列键)。我创建了以下实体父类(super class):

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

然后是组合键的父类(super class)(以及长主键的父类(super class),此处未列出):

@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 中的一个错误,因此我在 hibernate bug tracker 中创建了一个票证. 作为解决方法,我现在在 concreate 实体类而不是抽象父类(super class)中定义 ID 属性 (@EmbeddedId)。

关于java - JPA( hibernate ): Error when using @EmbeddedId in generic @MappedSuperclass,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/45933999/

相关文章:

java - 如何设置不是在 Java JPA/Hibernate 中自动生成的@Id 主键?

java - 设置世界风 map 的缩放级别

java - spring方法验证中如何验证方法参数默认为NotNull?

spring - 将手动创建的对象加载到 spring 上下文

java - 使用来自多个表的信息来记录交付的通用或特定 DAO?

java - 尝试在tomcat 9中加载maven项目,显示启动时子容器失败

hibernate - hibernate 查询:集合中是否包含某个对象?

java - 如何将 log4j 日志记录到现有的 J2EE Struts Web 应用程序?

java - Junit:在多个测试类中使用相同的测试对象

java - 如何将十进制代码点转换为 UTF-16 Hex(java 语法)?