英文:
Spring JPA Lazy loading @OneToOne entities doesn't work
问题
我在创建OrderEntity
对象时遇到了让BillingAddress
延迟加载的问题。我看到有很多关于这个问题的提问,并且按照指示进行了操作,包括添加了optional = false
,但是每当我使用findById
查找OrderEntity
时,BillingAddress
仍然被加载。
以下是我的实体类(为了简化问题而减少的代码):
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
具有引用订单的外键。我已经阅读了关于是否应该添加optional = false
以实现实体的延迟加载的矛盾答案,但对我来说似乎并不起作用。我在这些实体中是否遗漏了什么东西?
英文:
I'm having trouble making OrderEntity
object load BillingAddress
lazily. I've seen questions revolving around this asked a lot and followed instructions, including adding optional = false but BillingAddress
still gets loaded whenever I findById
an OrderEntity
.
These are my entities (reduced for the sake of this question):
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> {
}
The table billing_address
has a FK referencing orders. I've read contradicting answers saying adding optional = false
should load entities lazily, but for me, that doesn't seem to work. Am I missing something in any of these entities?
答案1
得分: 1
请查看Vlad Mihalcea的文章使用JPA和Hibernate映射@OneToOne关系的最佳方法。
正如文章中所述,其中一种解决方案是在父实体上删除关联...
@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)
关系。不过,我无法帮助你实现这一点,因为我自己从未尝试过。
英文:
Have a look at Vlad Mihalceas article The best way to map a @OneToOne relationship with JPA and Hibernate
As described there, one of the solutions would be to drop the relation on the parentside...
@Transient
private BillingAddressEntity billingAddress;
and load the BillingAddressEntity
manually using the shared id.
if (order.billingAddress == null)
{
order.billingAddress = entityManager.find(BillingAddressEntity.class, order.id);
}
<br>Another approach would be to drop the shared key, use a foreign key field instead and mark the relation as @ManyToOne
. This will sacrifice the OneToOne constraint check though.
@ManyToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
@JoinColumn(name = "billing_address_id")
private BillingAddressEntity billingAddress;
<br>Then there's also the byte code enhancement which would allow you to make this a @LazyToOne(LazyToOneOption.NO_PROXY)
relation. I can't help you with that though, as I've never done that myself.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论