spring-data-jpa 无法找到具有逻辑名称的列-使用@OneToMany和@JoinColumn时出现休眠异常

t5zmwmid  于 2022-11-10  发布在  Spring
关注(0)|答案(4)|浏览(161)

我在我的应用程序中有两个实体Orders和Products(一对多关联)。我的目标是在Order实体中建立单向OneToMany关系(我知道这不是最佳解决方案,但这是业务需求)。数据库模式由Liquibase生成,并由Hibernate验证。为了清晰起见,实体已被简化。数据库是Postgres。
尽管模式创建正确,但Hibernate仍会抛出异常:

Caused by: org.hibernate.cfg.RecoverableException: Unable to find column with logical name: productId in org.hibernate.mapping.Table(orders) and its related supertables and secondary tables
    at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:844) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
    at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:126) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
    at org.hibernate.cfg.annotations.CollectionBinder.bindCollectionSecondPass(CollectionBinder.java:1740) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
    ... 37 common frames omitted
Caused by: org.hibernate.MappingException: Unable to find column with logical name: productId in org.hibernate.mapping.Table(orders) and its related supertables and secondary tables
    at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:839) ~[hibernate-core-5.6.11.Final.jar:5.6.11.Final]
    ... 39 common frames omitted

为了证明模式生成正确,我用 @ManyToOne 替换了 @OneToMany 注解,它工作正常!突然之间,Hibernate能够找到该列。在那之后,我开始假设Hibernate中存在某种bug...
有没有人有一个想法,如何解决这个问题?
我的代码如下所示:

订单.java

@Entity
@Table(name = "orders")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Order {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long orderId;

    @Column
    private String clientName;

    @OneToMany
    @JoinColumn(name = "productIdFK", referencedColumnName = "productId")
    private List<Product> productList = new ArrayList<>();

}

产品.java

@Entity
@Table(name = "products")
@Data
@NoArgsConstructor
@AllArgsConstructor
@Builder
public class Product {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long productId;

    @Column
    private String name;
}

Liquibase脚本

{
  "databaseChangeLog": [
    {
      "changeSet": {
        "id": "Create PRODUCT table",
        "author": "me",
        "changes": [
          {
            "createTable": {
              "tableName": "products",
              "columns": [
                {
                  "column": {
                    "name": "productId",
                    "type": "bigint",
                    "constraints": {
                      "nullable": false,
                      "unique": true,
                      "primaryKey": true
                    }
                  }
                },
                {
                  "column": {
                    "name": "name",
                    "type": "varchar(250)",
                    "constraints": {
                      "nullable": true,
                      "unique": false
                    }
                  }
                }
              ]
            }
          },
          {
            "createTable": {
              "tableName": "orders",
              "columns": [
                {
                  "column": {
                    "name": "orderId",
                    "type": "bigint",
                    "constraints": {
                      "nullable": false,
                      "unique": true,
                      "primaryKey": true
                    }
                  }
                },
                {
                  "column": {
                    "name": "clientName",
                    "type": "varchar(250)",
                    "constraints": {
                      "nullable": true,
                      "unique": false
                    }
                  }
                },
                {
                  "column": {
                    "name": "productIdFK",
                    "type": "bigint",
                    "constraints": {
                      "nullable": true,
                      "unique": false
                    }
                  }
                }
              ]
            }
          }
        ]
      }
    }
  ]
}

liquibase脚本生成关系的片段

{
            "addForeignKeyConstraint": {
              "constraintName": "fk_product_order",
              "baseColumnNames": "productIdFK",
              "baseTableName": "orders",
              "referencedColumnNames": "productId",
              "referencedTableName": "products"
            }
          }
yebdmbv4

yebdmbv41#

@OneToMany
@JoinColumn(name = "orderId", referencedColumnName = "productId")// try orderId
private List<Product> productList = new ArrayList<>();
s3fp2yjn

s3fp2yjn2#

一旦你尝试了这个希望这会成功
Order.java中对此进行更改

@OneToMany(cascade = CascadeType.ALL, mappedBy= "order")
private List<Product> productList = new ArrayList<>();

请将其添加到Product.java

@ManyToOne
@JsonIgnore
private Order order;

请告诉我

wnrlj8wa

wnrlj8wa3#

你也应该试试这个。

@OneToMany(cascade = CascadeType.ALL, mappedBy = "order")
private List<Product> productList = new ArrayList<>();

与此沿着,请访问Product.java

@ManyToOne
@JoinColumn(name = "productId",
        foreignKey = @ForeignKey(
                name = "product_id_fk"))
private Order order;
gj3fmq9x

gj3fmq9x4#

首先,让我们弄清楚在您的模式中什么是1,什么是many。由于Order引用了Product,这意味着许多Order可能与同一个Product相关,不是吗?双向关系通常是首选关系,但您需要单向关系,它应该类似于

public class Order {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long orderId;

    @Column
    private String clientName;
}

public class Product {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long productId;

    @Column
    private String name;

    @OneToMany
    @JoinColumn(name = "productIdFK", referencedColumnName = "productId")
    private List<Order> orderList = new ArrayList<>();

}

相关问题