java - 无法使用复合 @IdClass 映射实体

标签 java hibernate jpa

我有以下模型(一个更大模型的非常简化的版本)

public enum EntityType {
    DOG, HAMMER
}

@Entity
public class Entity {
    @EmbeddedId
    private EntityKey key;
    private String someProp;
}

@Embeddable
public class EntityKey implements Serializable{
    private Long serial;
    @Enumerated(EnumType.STRING)
    private EntityType type;
}

@Entity
@IdClass(MetricKey.class)
public class Metric {
    @Id
    private EntityKey entityKey;
    @Id
    private Long timestamp;
    private Double sampledValue;
}

public class MetricKey implements Serializable {
    private EntityKey entityKey;
    private Long timestamp;
}

实体实际上是一个位于大型层次结构根部的抽象类。指标表示在特定时间点对实体采样的一些数据。实体有一个由类型和序列号组成的复合键,度量应该有一个由实体键+时间戳组成的复合键。

上面的代码让我从 hibernate 中得到这个异常:

org.hibernate.HibernateException: Unable to instantiate default tuplizer [org.hibernate.tuple.component.PojoComponentTuplizer]
    ...
Caused by: java.lang.reflect.InvocationTargetException
    ...
Caused by: org.hibernate.PropertyNotFoundException: field [serial] not found on Metric
    at org.hibernate.property.DirectPropertyAccessor.getField(DirectPropertyAccessor.java:166)
    ... 45 more

看起来它在 EntityKey 上发现了 @Embeddable 并试图在这里将其分解。

我知道我可以通过制作 MetricKey @Embeddable 并重写一些代码来解决这个问题:

@Entity
public class Metric {
    @EmbeddedId
    private MetricKey key;
    private Double sampledValue;
}
@Embeddable
public class MetricKey implements Serializable{
    private EntityKey entityKey;
    private Long timeStamp;
}

但我更喜欢原始设计,因为 EntityKey 在整个系统中广泛使用,并且必须在 EntityKeyMetricKey< 之间来回转换 会惹恼开发人员。

我做错了什么?

最佳答案

我可以建议您的唯一有效解决方案是将 Metric 的实现更改为

@Entity
@IdClass(MetricKey.class)
public class Metric {
    @Id
    @ManyToOne
    private Entity entity;
    @Id
    private Long timestamp;
    private Double sampledValue;
}

您还可以查阅 JPA 2.1 规范的2.4.1.1 派生身份规范

If an Id attribute in the entity is a many-to-one or one-to-one relationship to a parent entity, the corresponding attribute in the id class must be of the same Java type as the id class or embedded id of the parent entity (if the parent entity has a composite primary key) or the type of the Id attribute of the parent entity (if the parent entity has a simple primary key).

我的解决方案针对 Hibernate 4.3.6 进行了测试

关于java - 无法使用复合 @IdClass 映射实体,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25245838/

相关文章:

java - 具有供应商特定属性的 JPA find() 方法

java - 无法让 REST WS 与 Netbeans 一起工作

jpa - Liquibase 和 JPA 注释实体

java - 在数据库中存储语言的最佳实践

java.lang.NullPointerException 错误 - Intellij IDEA、Selenium、Java

java - 从 JTable 获取数据到 jText 字段,但出现空指针异常

java - 文件数据源路径不是动态出现的

java - hibernate二级缓存很慢

java - 在 Java 8 中延迟返回第一个非空列表

java - 如果将自定义查询与 JOIN 结合使用,则 Hibernate AttributeConverter 会失败