Однонаправленное отображение JPA OneToMany с дочерним объектом, имеющим составной первичный ключ, одно поле которого является внешним ключом - PullRequest
0 голосов
/ 22 апреля 2020

У меня есть JPA / Hibernate, как показано ниже, в одном из моих проектов, где я использую spring-data-jpa в слое постоянства.

@Entity
public class SalesOrder {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    Integer id;

    @OneToMany(fetch = FetchType.EAGER, orphanRemoval = true, cascade = CascadeType.ALL)
    @JoinColumn(name = "salesOrderId", referencedColumnName = "id", nullable = false)
    List<OrderLine> lines = new ArrayList<>();

    //...
}


@Entity
@IdClass(SalesOrderLinePK.class)
public class SalesOrderLine {
    @Id
    String sku;

    @Id
    @Column(name = "salesOrderId", insertable = false, updatable = false)
    Integer salesOrderId;

    //...
}

public class SalesOrderLinePK implements Serializable {
    String sku;
    Integer salesOrderId;
    OrderLinePK() {} 

    OrderLinePK(String sku, Integer salesOrderId) {
        this.sku = sku;
        this.salesOrderId= salesOrderId;
    }
}

Когда я сохраняю новый Order сущность с некоторыми новыми OrderLine дочерними объектами выдает ошибку из-за того, что salesOrderId поле SalesOrderLine не установлено, вместо этого быть нулевым.

Ниже приведен конкретный контрольный пример, который завершается с ошибкой.

@Test
void create() {
    SalesOrder item = randomItem(false);
    item = salesOrderService.create(item);

    assertNotNull(item);
    assertNotNull(item.getId());
    assertNotNull(item.getVersion());
}

private SalesOrder randomItem(boolean persistant) {
    String random = RandomString.make(5);
    SalesOrder order = new SalesOrder();
    order.setOrderDate(LocalDate.now());
    order.setOrderState(OrderState.DONE);
    for(int i = 0; i < 5; i++) {
        SalesOrderLine item = new SalesOrderLine();
        item.setIdx(i);
        item.setCode(random);
        item.setName("Catalog Item " + random);
        item.setListedPrice(BigDecimal.valueOf(120.50));
        item.setDiscount(BigDecimal.valueOf(10));
        item.setSellingPrice(BigDecimal.valueOf(108.50));
        order.getOrderLines().add(item);
    }


    if (persistant) {
        order = salesOrderRepository.save(order);
    }
    return order;
}

Я не могу понять, что я делаю здесь неправильно. Я тоже не хочу, чтобы это делало двунаправленным. Не могли бы вы помочь мне решить эту проблему.

...