首先,对KLE的回答进行一些澄清:
不受约束(可为空)的一对一关联是唯一一个在没有字节码检测的情况下无法代理的关联。这样做的原因是所有者实体必须知道关联属性是否应该包含代理对象或 NULL,并且由于通常通过共享 PK 进行一对一映射,因此它无法通过查看其基表的列来确定这一点,因此它无论如何都必须急切地获取代理,这使代理毫无意义。这里有更详细的解释。
多对一关联(显然是一对多)不会受到这个问题的影响。Owner 实体可以很容易地检查自己的 FK(如果是一对多,最初创建空集合代理并按需填充),因此关联可以是惰性的。
用一对多代替一对一几乎不是一个好主意。您可以用独特的多对一替换它,但还有其他(可能更好)选项。
Rob H.有一个有效的观点,但是您可能无法根据您的模型实现它(例如,如果您的一对一关联可以为空)。
现在,就原始问题而言:
A)@ManyToOne(fetch=FetchType.LAZY)
应该工作得很好。您确定它没有在查询本身中被覆盖吗?可以join fetch
在 HQL 中指定和/或通过 Criteria API 显式设置获取模式,这将优先于类注释。如果情况并非如此,并且您仍然遇到问题,请发布您的课程、查询和生成的 SQL,以便进行更深入的对话。
B)@OneToOne
更棘手。如果它绝对不可为空,请按照 Rob H. 的建议进行指定,如下所示:
@OneToOne(optional = false, fetch = FetchType.LAZY)
否则,如果您可以更改数据库(将外键列添加到所有者表),请执行此操作并将其映射为“已加入”:
@OneToOne(fetch = FetchType.LAZY)
@JoinColumn(name="other_entity_fk")
public OtherEntity getOther()
在其他实体中:
@OneToOne(mappedBy = "other")
public OwnerEntity getOwner()
如果你不能这样做(并且不能忍受急切的获取)字节码检测是你唯一的选择。但是,我必须同意CPerkins的观点——如果你有80 个!!!由于急切的 OneToOne 协会而加入,那么您将遇到更大的问题 :-)