我有以下实体:
@Entity
@Table(name = "user_data")
public class UserData {
...
@ManyToOne
private User user;
...
}
@Entity
@Table(name = "user_cars")
public class UserCar {
...
private Integer userId;
...
}
@Entity
@Table(name = "users")
public class User {
...
@OneToMany(mappedBy = "userId", cascade = CascadeType.ALL)
private List<UserCar> userCars;
...
}
如您所见,usercars的加载很慢(我不打算更改它)。现在我使用规范来获取用户数据:
public Page<UserData> getUserData(final SpecificationParameters parameters) {
return userDataRepository.findAll(createSpecification(parameters), parameters.pageable);
}
private Specification<UserData> createSpecification(final SpecificationParameters parameters) {
final var clazz = UserData.class;
return Specification.where(buildUser(parameters.getUserId()));
}
private Specification<UserData> buildUser(final Integer userId) {
return (root, criteriaQuery, criteriaBuilder) -> {
if (Objects.nonNull(userId)) {
final Join<UserData, User> joinParent = root.join("user");
return criteriaBuilder.equal(joinParent.get("id"), userId);
} else {
return criteriaBuilder.isTrue(criteriaBuilder.literal(true));
}
};
}
但是我不知道如何添加fetchjoin子句来获取用户汽车。我尝试在不同的地方添加它,我得到了lazyinitializationexception(所以它不起作用)或者其他一些异常。。。
2条答案
按热度按时间rta7y2nd1#
与前面的回答略有不同,但我认为jcc提到的想法是正确的,即“hibernate正在抱怨,因为它无法找到usercars关系的所有者,在本例中是用户。”
为此,我想知道对象关系引擎是否因为直接链接到userid(原语)而不是用户(实体)而变得混乱。我不确定它是否可以假定“userid”原语必然意味着与用户实体的连接。
是否可以尝试重新安排Map,使其不在联接表中使用整数userid,而是使用对象本身,然后查看是否允许实体管理器更好地理解您的查询?
因此Map可能如下所示:
这也将更符合https://www.baeldung.com/hibernate-one-to-many
q3aa05252#
除了问题评论中提供的建议@crizzis外,请尝试
join fetch
这个user
关系;在您报告的错误中:hibernate抱怨找不到主人,
user
在这种情况下userCars
关系。这在某种程度上是奇怪的,因为
@ManyToOne
这段关系将急切地得到回报user
实体和它也将在获得userData
但是hibernate可能在实际的获取阶段之前执行查询分析。如果有人能就这一点提供一些额外的见解,那就太好了。话虽如此,请考虑将fetch策略显式设置为
FetchType.LAZY
在你的@ManyToOne
关系:你的
Specification
代码可以如下所示:我之前没有注意实体关系本身,但是atmas给了你一个很好的建议,事实上,它将是处理这种关系中的数据的更有效的方法。
至少,定义
User
以及UserCars
使用@JoinColumn
注解,而不是通过非实体字段进行Map,以防止实体出现错误或不正确的行为。例如,考虑: