有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

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

我在使OrderEntity对象加载BillingAddress时遇到问题。我看到围绕这个问题问了很多问题,并按照说明进行了操作,包括添加optional=false,但每当我findByIdan OrderEntityBillingAddress仍然会被加载

这些是我的实体(为了这个问题而减少):

订单实体

@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;

}

BillingAddressEssentialty

@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应该懒散地加载实体,但对我来说,这似乎不起作用。我在这些实体中遗漏了什么吗


共 (1) 个答案

  1. # 1 楼答案

    看看弗拉德·米哈尔塞斯的文章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)关系。不过我帮不了你,因为我自己从来没这么做过