I have got two entities in my application Orders and Products (one-to-many association). I am aiming to set up a unidirectional OneToMany relationship in Order entity (I'm aware that it is not the best solution, however this is a business requirement). The database schema is generated by Liquibase and validated by Hibernate. Entities have been simplified for the sake of clarity. Database is Postgres.
Although the schema is created correctly, Hibernate throws an exception:
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
To prove that the schema is generated appropriately, I replaced @OneToMany annotation with @ManyToOne and it works fine! All of the sudden, Hibernate is able to find the column. After that I began assuming that there is some kind of bug in Hibernate...
Does anyone have an idea, how to solve this issue?
My code looks as follows:
Order.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<>();
}
Product.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 script
{
"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
}
}
}
]
}
}
]
}
}
]
}
Snippet from liquibase script generating relationships
{
"addForeignKeyConstraint": {
"constraintName": "fk_product_order",
"baseColumnNames": "productIdFK",
"baseTableName": "orders",
"referencedColumnNames": "productId",
"referencedTableName": "products"
}
}
CodePudding user response:
@OneToMany
@JoinColumn(name = "orderId", referencedColumnName = "productId")// try orderId
private List<Product> productList = new ArrayList<>();
CodePudding user response:
Once you try this hope this will work out
change to this in Order.java
@OneToMany(cascade = CascadeType.ALL, mappedBy= "order")
private List<Product> productList = new ArrayList<>();
add this in Product.java
@ManyToOne
@JsonIgnore
private Order order;
let me know