java - Hibernate 查找错误的主键

标签 java spring hibernate spring-data-jpa

我的实体有两个外键,其中之一是主键。我在JPA Wiki中读到如果子级(采购)主键与父级(商品)主键相同,则建立 @OneToOne 关系。

@SuppressWarnings("serial")
@Entity
public class Procurement implements Serializable {

    @Id
    @OneToOne
    // the child's primary key is the same as the parent
    @JoinColumn(name = "articleId", referencedColumnName = "id")
    private Article article;

    @OneToOne
    @JoinColumn(name = "supplierId", referencedColumnName = "id")
    private Supplier supplier;

按照标准方法,JpaRepository 应如下所示:

@Repository
public interface IProcurementRepository extends
        JpaRepository<Procurement, Article>

但是,如果我想调用 findOne 方法(查找主键)来传递“Article”对象,Hibernate 会抛出异常。

org.hibernate.TypeMismatchException: Provided id of the wrong type for class de.willms.spring.myerp.model.Procurement. Expected: class de.willms.spring.myerp.model.Procurement, got class de.willms.spring.myerp.model.Article

数据库表结构:

表“文章”(ID、短文本)

表“供应商”(ID、名称)

表“采购”(文章ID、供应商ID、价格)

我需要更改什么才能通过相应的“文章”对象找到“采购”记录?

最佳答案

最后,我在 Hibernate 中发现了一个特殊的函数(令人惊奇,但在文档中很难理解),从而找到了解决方案。

一旦主键由多个列组成,或者像我的例子一样,与其他表相关,就必须编写一个特殊的 ID 类。

@Embeddable    
public class Procurement_ID implements Serializable {

    /**
     * This attribute establishes the 1:1 connection to a record in the
     * "article" table. The column "articleId" is a foreign key to the column
     * "id" in the {@link Article} entity. (Warning: This is Hibernate
     * specific!)
     */
    @OneToOne
    @JoinColumn(name = "articleId", referencedColumnName = "id")
    private Article article;

    /**
     * This attribute establishes the 1:1 connection to a record in the table
     * "supplier". The column "supplierId" is a foreign key to the column "id"
     * in the {@link Supplier} entity. (Warning: This is Hibernate specific!)
     */
    @OneToOne
    @JoinColumn(name = "supplierId", referencedColumnName = "id")
    private Supplier supplier;

(由于更加“规范化”的数据模型,我切换到复合主键。)

由于@Embeddable注解的存在,这个ID可以注入(inject)到实体类中。

@Entity
public class Procurement implements Serializable {

    /**
     * The composite primary key of the underlying table is defined in the
     * {@link Procurement_ID} class.
     */
    @EmbeddedId
    private Procurement_ID procid;

当我使用这种方法时,Hibernate 会插入一 strip 有正外键检查的新记录:

[DEBUG] Generated identifier: component[article,supplier]{article=de.willms.spring.myerp.model.Article#1, supplier=de.willms.spring.myerp.model.Supplier#1}, using strategy: org.hibernate.id.CompositeNestedGeneratedValueGenerator

... (Flusing) ...

[DEBUG] Listing entities: ... de.willms.spring.myerp.model.Procurement{price=2.5, deliveryTime=10, procid=component[article,supplier]{article=de.willms.spring.myerp.model.Article#1, supplier=de.willms.spring.myerp.model.Supplier#1}, priceUnit=$}

然而,遗憾的是,JpaRepository 无法注入(inject)仅涉及主键一部分的 find() 方法 stub 。它“无法根据路径解析属性”。欢迎大家留言评论!

关于java - Hibernate 查找错误的主键,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15897354/

相关文章:

java - Spring JPA和Hibernate在调用save方法时不将实体保存到数据库

Java 泛型,返回泛型扩展

java - java - 如何将整数列表与java流相加?

java - Maven 不包括 commons-logging

jquery - 当路径变量包含 (.) 时,@ResponseBody 不起作用

java - POM.xml依赖错误

使用 XMLSerializer 使根元素成为数组的 Java XML 到 JSON

java - 在 com.spring.schoolmanagement.model.Subject 类型上找不到属性 'id'

Java spring集成网关请求响应时间记录

java - 带有 H2 JPA 的 Spring boot 和 JUnit 导致找不到 'pg_class'