【问题标题】:Can't save entity with composite key无法使用复合键保存实体
【发布时间】:2017-05-25 23:39:13
【问题描述】:

在使用复合键时尝试保存实体时出现异常。这是我尝试保存到的异常、模型和存储库。有人可以帮忙吗?

org.springframework.beans.TypeMismatchException:转换失败 'org.CheckType_$$_jvst96c_4' 类型的属性值到所需类型 属性“checkType”的“int”;嵌套异常是 java.lang.IllegalArgumentException:无法转换类型的值 'org.CheckType_$$_jvst96c_4' 到所需的属性类型'int' 'checkType':属性编辑器 [org.springframework.beans.propertyeditors.CustomNumberEditor] 返回 '​​org.CheckType_$$_jvst96c_4' 类型的不适当值

@Entity
public class CheckType {
    @Id
    private int id;

    @NotNull
    private String name;

    @OneToMany(mappedBy = "checkType")
    private List<ClientCheck> checks;
    //getters and setters
}

@Entity
public class Offer {
    @Id
    @Column(name = "offerid")
    private Integer offerId;
    //...
    @OneToMany(mappedBy = "offer")
    private List<ClientCheck> clientCheckList;

    //getters and setters
}

@Entity
@IdClass(ClientCheckId.class)
public class ClientCheck {
    @Id
    @ManyToOne
    @JoinColumn(name = "offer_id", referencedColumnName = "offerid")
    private Offer offer;

    @Id
    @ManyToOne
    @JoinColumn(name = "check_type_id", referencedColumnName = "id")
    private CheckType checkType;

    @Id
    private Date timestamp;

    private String result;
    //getters and setters
}

public class ClientCheckId implements Serializable {
    private int offer;
    private int checkType;
    private Date timestamp;

    //getters and setters
    //equals and hashCode
}

public interface ClientCheckRepo extends JpaRepository<ClientCheck, ClientCheckId> {
}

【问题讨论】:

  • 上下文是什么?你是如何创建和保存这个实体的?通过 MVC 请求?
  • 我不知道上下文是否重要;我在控制器上收到一个请求,制作/保存报价,创建时间戳,读取检查类型,并为每个获取检查结果,然后使用所有参数集保存检查。
  • 上下文很重要,因为错误“org.springframework.beans.TypeMismatchException”表明问题在于请求参数的绑定。能否贴出相关的控制器代码。
  • 调用控制器中的“clientCheckRepo.save(clientCheck)”时发生异常。现在,这是在服务层。
  • 您的实体映射似乎有效(根据 JPA 2.1 规范)。也许是 Spring-Data 中的错误?您使用的是最新版本吗?

标签: java hibernate jpa spring-data


【解决方案1】:

如果另一个实体是复合键的一部分,则必须在 ID 类中声明该实体,而不是其 ID:

public class ClientCheckId implements Serializable {
    private int offer;
    private CheckType checkType;
    private Date timestamp;

    //getters and setters
    //equals and hashCode
}

如果您想了解 Hibernate 的工作方式,则错误消息非常易读:org.CheckType_$$_jvst96c_4 是您的类的丰富版本,Hibernate 尝试通过反射分配给ClientCheckIdcheckType 字段,但由于类型不兼容而失败.

【讨论】:

  • 当我这样做时它起作用了,但是当我也改变了报价类型(int->报价)时却没有。为什么 Offer 和 CheckType 不一样?!
  • 不是 JPA 2.1 规范所说的:“如果实体中的 Id 属性与父级是多对一或一对一关系实体,id 类中的相应属性必须与 [...] 父实体的 Id 属性的类型具有相同的 Java 类型”。请参阅2.4.1.1 派生身份规范
  • 我也遇到了同样的问题,但我不知道为什么会这样。如果我同时使用实体名称(即 Offer 和 CheckType),它就不起作用。但是如果我使用 CheckType 和 int,或者 Offer 和 int,它就可以工作
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2019-01-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多