Spring JPA延迟加载@OneToOne实体不起作用

问题描述

我在延迟OrderEntity对象加载BillingAddress时遇到麻烦。我已经看到很多与此相关的问题,并遵循指示,包括添加optional = false,但是无论何时BillingAddressfindByIdOrderEntity仍然会加载。

这些是我的实体(为这个问题而简化):

OrderEntity

@Entity
@Table(name = "orders",schema = "glamitoms")
public class OrderEntity {

    @Id
    @Column(name = "id")
    private int id;

    @OnetoOne(mappedBy = "order",cascade = CascadeType.ALL,fetch = FetchType.LAZY,optional = false)
    private BillingAddressEntity billingAddress;

}

BillingAddressEntity

@Entity
@Table(name = "billing_address",schema = "glamitoms")
public class BillingAddressEntity {

    @Id
    @Column(name = "order_id")
    private int id;

    @OnetoOne(fetch = FetchType.LAZY)
    @MapsId
    private OrderEntity order;
}

TestController

@RestController
public class TestController {

    private OrdersDAO ordersDAO;

    @Autowired
    public TestController(OrdersDAO ordersDAO) {
        this.ordersDAO = ordersDAO;
    }

    @GetMapping("/test")
    public void test() {
        OrderEntity orderEntity = ordersDAO.findById(1).get();
    }
}

OrdersDAO

@Repository
public interface OrdersDAO extends JpaRepository<OrderEntity,Integer> {
}

billing_address具有FK引用顺序。我读过矛盾的答案,说添加optional = false应该延迟加载实体,但是对我来说,这似乎行不通。我在这些实体中是否缺少任何东西?

解决方法

看看Vlad Mihalceas的文章The best way to map a @OneToOne relationship with JPA and Hibernate

如此处所述,解决方案之一是将关系放到父母一方...

@Transient
private BillingAddressEntity billingAddress;

并使用共享ID手动加载BillingAddressEntity

if (order.billingAddress == null) 
{
   order.billingAddress = entityManager.find(BillingAddressEntity.class,order.id);
}


另一种方法是删除共享密钥,改用外键字段并将关系标记为@ManyToOne。但这会牺牲OneToOne约束检查。

@ManyToOne(cascade = CascadeType.ALL,fetch = FetchType.LAZY)
@JoinColumn(name = "billing_address_id")
private BillingAddressEntity billingAddress;


然后还有字节码增强功能,使您可以将其设为@LazyToOne(LazyToOneOption.NO_PROXY)关系。不过我无法为您提供帮助,因为我自己从未做到过。