持久化JPA会使嵌套对象的db外键字段为null

时间:2018-02-20 09:51:04

标签: java spring jpa spring-data-jpa

我有结构表:

orders
- id: bigint(20)
- amount: bigint(20)

order_details
- id: bigint(20)
- payment_type: varchar(255)
- order_fk: bigint(20)

实体:

MyOrderEntity

@Entity
@Table(name = "orders")
public class MyOrderEntity {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    public Long id;

    public Long amount;

    @OneToOne(fetch = LAZY, mappedBy = "order", cascade = ALL)
    public MyOrderDetailsEntity details;

}

MyOrderDetailsEntity

@Entity
@Table(name = "order_details")
public class MyOrderDetailsEntity {

    @Id
    @GeneratedValue(strategy = IDENTITY)
    public Long id;

    @OneToOne
    @JoinColumn(name = "order_fk")
    public MyOrderEntity order;

    public String paymentType;
}

存储库

@Repository
public interface MyOrderRepository extends JpaRepository<MyOrderEntity, Long> {}

我以这种方式坚持MyOrderEntity

MyOrderDetailsEntity details = new MyOrderDetailsEntity();
details.paymentType = "default";

MyOrderEntity order = new MyOrderEntity();
order.amount = 123L;
order.details = details;

myOrderRepository.save(order);

保存order后,我在null字段中有 order_details.order_fk 值。

我希望order_details.order_fk填充order.id

我该怎么做?

1 个答案:

答案 0 :(得分:1)

您还需要明确将MyOrderEntity设置为MyOrderDetailsEntity。 JPA实现不适合您。所以添加一行:

details.order = order;
保存前

您还可以将以下方法添加到MyOrderEntity

@PrePersist
private void prePersist() {
    if(null!=details) details.order=this;
}

要避免样板代码,请将MyOrderDetailsEntity设置为MyOrderEntity

但最好的方法是设置MyOrderDetailsEntity.details字段private并创建一个类似的setter:

setDetails(MyOrderDetailsEntity details) {
    this.details = details;
    details.order = this;
}

即使在坚持之前也始终保持正确设置。最佳策略取决于具体情况。

有关详细信息,请参阅this question and answers