gpt4 book ai didi

java - JPA 2 实体中的多个 @CollectionTable 导致不相关的外部联接

转载 作者:行者123 更新时间:2023-11-30 03:25:21 26 4
gpt4 key购买 nike

您好,我有以下 JPA 实体类。它有两个用于组和联系人 ID 的 @CollectionTable 映射。我很感兴趣从 contact_details 表中获取唯一联系人 ID 的列表,并在下面的 Users 类变量 contacts 中引用它们:

@Entity
@Table(name = "users")
public class User {

@Id
@GeneratedValue(generator="uuid")
@GenericGenerator(name = "uuid", strategy = "uuid2")
private UUID id;

@NotBlank
private String username;

@NotBlank
@Column(name = "name")
private String name;

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "users_groups", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "[group]")
private List<String> groups = new ArrayList<>();

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "contact_detail", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "[id]")
private List<String> contacts = new ArrayList<String>();
}

当我从数据库获取用户时,它会在 hibernate 日志中生成以下查询

select user0_.id, user0_.password, user0_.username, contacts1_.user_id as user_id8_4_1_, contacts1_."id" as id1_2_1_, groups2_.user_id as user_id1_4_2_, groups2_."group" as group2_5_2_ 
from users user0_
left outer join contact_detail contacts1_ on user0_.id=contacts1_.user_id
left outer join users_groups groups2_ on user0_.id=groups2_.user_id
where user0_.id=?

由于 contact_detailusers_groups 上的左外连接,它实际上会多次检索到相同的 contact_id。这是具有多个“47e5b98a-2116-4ad9-b773-3acc99e2c83c”联系人 ID 的实体的 JSON 表示形式

{
user: {
id: "d3b3be2a-8a2a-48ac-94dd-fd85faf1a8ff",
username: "shiv",
firstName: "Shivam",
lastName: "Sinha",
groups: [
"ADMIN",
"USER",
"ROOT"
],
expired: false,
locked: false,
credentialsExpired: false,
enable: true,
birthday: "2015-05-18",
joined: "2015-05-18",
gender: "M",
contactDetails: null,
contacts: [
"47e5b98a-2116-4ad9-b773-3acc99e2c83c",
"47e5b98a-2116-4ad9-b773-3acc99e2c83c",
"47e5b98a-2116-4ad9-b773-3acc99e2c83c"
]
}
}

但是,当我完全删除以下组类变量时:

@ElementCollection(fetch = FetchType.EAGER)
@CollectionTable(name = "users_groups", joinColumns = @JoinColumn(name = "user_id"))
@Column(name = "[group]")
private List<String> groups = new ArrayList<>();

并尝试从数据库中检索用户。 Hibernate生成以下sql:

select user0_.id, user0_.password, user0_.username, contacts1_.user_id as     user_id8_4_1_, contacts1_."id" as id1_2_1_ 
from users user0_ left outer join contact_detail contacts1_ on user0_.id=contacts1_.user_id
where user0_.id=?

这是实体的 JSON 表示形式:

{
user: {
id: "d3b3be2a-8a2a-48ac-94dd-fd85faf1a8ff",
username: "shiv",
firstName: "Shivam",
lastName: "Sinha",
expired: false,
locked: false,
credentialsExpired: false,
enable: true,
birthday: "2015-05-18",
joined: "2015-05-18",
gender: "M",
contacts: [
"47e5b98a-2116-4ad9-b773-3acc99e2c83c"
]
}
}

它仅包含唯一的联系人 ID“47e5b98a-2116-4ad9-b773-3acc99e2c83c”。这正是我们所期望的。

所以我的问题是如何实现同样的事情,而不必删除 groups 类变量或从 List<String> contacts 更改数据类型至Set<String> contacts

最佳答案

现在发生的行为正如从 hibernate 中看到的那样 FAQ .这里的常见问题解答中也提到了解决方案

如果您想通过 JPA 执行此操作,请参阅 here .

以下是使用以下规范在 Spring 数据中的实现

 public class UserSpecifications {

public static Specification<User> findUniqueUser(Integer userId){

return new Specification<User>() {

@Override
public Predicate toPredicate(Root<User> userRoot,
CriteriaQuery<?> criteriaQ, CriteriaBuilder critieriaB) {
criteriaQ.distinct(true);
return critieriaB.equal(userRoot.get(User_.id), 1);
}

};
}
}

查找记录

User user = userRepository.findOne(UserSpecifications.findUniqueUser(1));

关于java - JPA 2 实体中的多个 @CollectionTable 导致不相关的外部联接,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30366789/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com