多对多注释未在选择查询中生成连接
Posted
技术标签:
【中文标题】多对多注释未在选择查询中生成连接【英文标题】:ManyToMany annotations not generating join in select query 【发布时间】:2019-08-19 08:50:48 【问题描述】:总结: 我正在尝试使用 jpa + hibernate 建立并急切地检索单向多对多关系。
在做findAll()时,引用的实体是空的,应该有1个。
hibernate 生成的 SQL(使用 show-sql 属性)缺少我所看到的连接。
上下文:
Spring 数据 - 4.0.4.RELEASE 休眠 - 4.2.21.Final我尝试过的一些替代方案/修复:
已尝试将它们切换为 OneToMany/ManyToOne 关系。 已尝试通过使用 mappedBy 引用来自 Student 的 Class 来设置双向多对多关系 已尝试将 Class 的 id 列更新为在连接表中不存在差异Java 实体
@Data
@Entity
@Table(name = "student")
public class Student
@Column(name = "student_id", unique = true, nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Data
@Entity
@Table(name = "Class")
public class Class
@Column(name = "id", unique = true, nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "class_student",
joinColumns = @JoinColumn(name = "class_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "student_id"))
private Set<Student> students;
DDL:
CREATE TABLE IF NOT EXISTS `student` (
student_id INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`student_id `)
);
CREATE TABLE IF NOT EXISTS `class` (
`id` INT NOT NULL AUTO_INCREMENT,
PRIMARY KEY (`id`)
);
CREATE TABLE IF NOT EXISTS `class_student ` (
student_id INT NOT NULL,
class_id INT NOT NULL,
PRIMARY KEY (`student_id `, `class_id`),
CONSTRAINT `fk_student_id` FOREIGN KEY (`student_id`) REFERENCES `student` (`student_id`),
CONSTRAINT `fk_class_id` FOREIGN KEY (`class_id`) REFERENCES `class` (`id`)
);
实际与预期:
当我classRespository.getAll()
时实际生成的 sql 似乎缺少我所期望的 class + class_student 之间的连接。
它还奇怪地包括了 student 和 class_student 之间的连接,这是我没想到的,因为它是单向定义的,而且除了可能被丢弃之外,我不知道对该意外查询的结果做了什么。
实际生成的 SQL:
Hibernate:
select
classin0_.id as id1_29_,
from
class classin0_
INNER JOIN
post_tag pt
ON p.id = pt.post_id
INNER JOIN
tag t
ON pt.tag_id = t.id
WHERE p.id = 1
Hibernate:
select
class_student0_.class_id as id1_30_1_,
class_student0_.student_id as featured2_10_1_,
student1_.student_id as featured1_28_0_,
from
class_student class_student0_
inner join
student student1_
on class_student0_.student_id=student1_.student_id
where
class_student0_.id=?
我希望 jpa 可以在三个表中进行内部连接的查询可以解析回一个集合。
任何帮助将不胜感激。
【问题讨论】:
仅供参考,急切地获取 ManyToMany 通常是个坏主意,因为返回的数据可能会导致大量重复。 附注 - 不要命名类Class
,想出类似Lecture
之类的东西。否则可能会导致很多问题。
@sp00m 那么将其视为ManyToOne会更好吗?
@Amongalen 哦同意了,只是这个问题的(糟糕的)临时名称,它不是学生 - 现实中的班级关系
【参考方案1】:
我检查了你的映射——它是正确的。我正在使用这些类。
@Entity
@Table(name = "student")
public class Student
@Column(name = "student_id", unique = true, nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "name")
private String name;
@Entity
@Table(name = "Class")
public class Class
@Column(name = "id", unique = true, nullable = false)
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(name = "className")
private String className;
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(
name = "class_student",
joinColumns = @JoinColumn(name = "class_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "student_id", referencedColumnName = "student_id"))
private Set<Student> students;
当我 classRespository.getAll() 时实际生成的 sql 似乎缺少我期望的 class + class_student 之间的连接。奇怪的是,它还包含了我没想到的 student 和 class_student 之间的连接
Hibernate 不对 class
和 class_student
关系使用连接。
Hibernate 通过第一次查询获取所有类
select
class0_.id as id1_0_,
class0_.className as classNam2_0_
from
Class class0_
然后在class_student
和student
之间使用inner join
让现有班级的所有学生。
select
students0_.class_id as class_id1_1_0_,
students0_.student_id as student_2_1_0_,
student1_.student_id as student_1_2_1_,
student1_.name as name2_2_1_
from
class_student students0_
inner join
student student1_
on students0_.student_id=student1_.student_id
where
students0_.class_id=?
我无法检查您的 SQL,因为它不正确。
例如class_student
表中没有class_student0_.id=?
这样的字段。
【讨论】:
抱歉,连接表中的id
应该是class_id
。
@GavinFitzgerald 最好提供真正的 SQL 或使用 Class
、Student
实体进行测试。以上是关于多对多注释未在选择查询中生成连接的主要内容,如果未能解决你的问题,请参考以下文章
MySQL 基础 -- 多表关系(一对一1对多(多对一)多对多)多表查询(内连接外连接自连接子查询(嵌套查询)联合查询 union)笛卡儿积