问题描述
我在延迟OrderEntity
对象加载BillingAddress
时遇到麻烦。我已经看到很多与此相关的问题,并遵循指示,包括添加optional = false,但是无论何时BillingAddress
和findById
,OrderEntity
仍然会加载。
这些是我的实体(为这个问题而简化):
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)
关系。不过我无法为您提供帮助,因为我自己从未做到过。