我在使OrderEntity
对象延迟加载BillingAddress
时遇到问题。我看到了很多围绕这个问题的问题,并遵循了说明,包括添加optional=false,但每当我findById
和OrderEntity
时,BillingAddress
仍然会被加载。
这些是我的实体(为了这个问题而减少(:
订单实体
@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;
}
测试控制器
@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();
}
}
订单DAO
@Repository
public interface OrdersDAO extends JpaRepository<OrderEntity, Integer> {
}
表billing_address
具有FK引用顺序。我读过一些自相矛盾的答案,说添加optional = false
应该延迟加载实体,但对我来说,这似乎不起作用。我在这些实体中遗漏了什么吗?
看看Vlad Mihalceas的文章用JPA和Hibernate 映射@OneToOne关系的最佳方法
正如那里所描述的,解决方案之一是放弃父母一方的关系。。。
@Transient
private BillingAddressEntity billingAddress;
并使用共享id手动加载CCD_ 8。
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)
关系。不过我帮不了你,因为我自己从来没有这样做过。