具有 JoinTable 关系的 ManyToOne 无法正常工作
ManyToOne with JoinTable relationship doesn't work properly
我有一个部门实体,一个部门最多只能有一个地址,一个地址也是一个实体,可以在多个部门之间共享。
为了在休眠中练习 ManyToOne 关系,我决定有一个 JoinTable,这是我的实体定义:
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Getter
@Setter
@Entity(name = "Address")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String city;
}
地址实体:
@Getter
@Setter
@Entity(name = "department")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "person_id")
private Person manager;
// many departments can have the same address
// one department should have at most one address
// todo not working as expected, we are not fetching the address of the department
@ManyToOne(fetch = FetchType.EAGER)
@JoinTable(name = "department_address",
joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "department_id", referencedColumnName = "id"))
private Address address;
}
Person 实体(为示例的完整性而添加):
@Getter
@Setter
@Entity(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id")
private Address address;
}
当使用 spring 数据 jpa 从数据库中检索部门时,就好像我们没有获取与部门关联的地址数据。
这里是数据库的内容:
Table部门
id
name
person_id
23
IT
3
Table地址
id
name
2
Paris
3
kharajiv
Table department_address
id
address_id
department_id
2
2
23
存储库定义:
public interface DepartmentRepository extends JpaRepository<Department, Long> {}
查找给定部门时,以我为例,它是部门 23,departments/23:
Department department = departmentRepository.findById(id).get();
Address address = department.getAddress();
System.out.println("address = " + address);
地址始终为空,即使对于部门 23,table department_address 中有一行,这里是部门
的输出
System.out.println("department = " + department);
department = Department(id=23, name=IT, manager=Person(id=3, name=hamida, address=Address(id=3, city=kharajiv)), address=null)
这是打印的 sql 查询:
Hibernate: select department0_.id as id1_1_0_, department0_.person_id as person_i3_1_0_, department0_.name as name2_1_0_, department0_1_.department_id as departme1_2_0_, person1_.id as id1_3_1_, person1_.address_id as address_3_3_1_, person1_.name as name2_3_1_, address2_.id as id1_0_2_, address2_.name as name2_0_2_, address3_.id as id1_0_3_, address3_.name as name2_0_3_ from department department0_ left outer join department_address department0_1_ on department0_.id=department0_1_.address_id left outer join person person1_ on department0_.person_id=person1_.id left outer join Address address2_ on person1_.address_id=address2_.id left outer join Address address3_ on department0_1_.department_id=address3_.id where department0_.id=?
@JoinTable注解用于指定many-to-manytable关系的映射。在这种情况下使用@ManyToMany
左外连接地址 address3_ on department0_1_.department_id=address3_.id whe
可能我看错了,deparment id和address id不匹配。必须是 deparment0_1.address_id = address3_.id
能否尝试将 inversecolumn 更改为 address_id
joinColumns = @JoinColumn(name = "deparment_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"))
private Address address
joinColumns:分配与实体(在您的案例中为部门)相关的第三个table 列。
inverseJoinColumns:分配第三列table与关联实体(您的情况下的地址)相关。
你的反了。您在 inverseJoinColumns 中拥有实体(部门),在 joinColumns
中拥有地址
我有一个部门实体,一个部门最多只能有一个地址,一个地址也是一个实体,可以在多个部门之间共享。
为了在休眠中练习 ManyToOne 关系,我决定有一个 JoinTable,这是我的实体定义:
import lombok.Getter;
import lombok.Setter;
import javax.persistence.*;
@Getter
@Setter
@Entity(name = "Address")
public class Address {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
@Column(name = "name")
private String city;
}
地址实体:
@Getter
@Setter
@Entity(name = "department")
public class Department {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@ManyToOne
@JoinColumn(name = "person_id")
private Person manager;
// many departments can have the same address
// one department should have at most one address
// todo not working as expected, we are not fetching the address of the department
@ManyToOne(fetch = FetchType.EAGER)
@JoinTable(name = "department_address",
joinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "department_id", referencedColumnName = "id"))
private Address address;
}
Person 实体(为示例的完整性而添加):
@Getter
@Setter
@Entity(name = "person")
public class Person {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Long id;
private String name;
@OneToOne(cascade = CascadeType.ALL)
@JoinColumn(name = "address_id")
private Address address;
}
当使用 spring 数据 jpa 从数据库中检索部门时,就好像我们没有获取与部门关联的地址数据。
这里是数据库的内容:
Table部门
id | name | person_id |
---|---|---|
23 | IT | 3 |
Table地址
id | name |
---|---|
2 | Paris |
3 | kharajiv |
Table department_address
id | address_id | department_id |
---|---|---|
2 | 2 | 23 |
存储库定义:
public interface DepartmentRepository extends JpaRepository<Department, Long> {}
查找给定部门时,以我为例,它是部门 23,departments/23:
Department department = departmentRepository.findById(id).get();
Address address = department.getAddress();
System.out.println("address = " + address);
地址始终为空,即使对于部门 23,table department_address 中有一行,这里是部门
的输出System.out.println("department = " + department);
department = Department(id=23, name=IT, manager=Person(id=3, name=hamida, address=Address(id=3, city=kharajiv)), address=null)
这是打印的 sql 查询:
Hibernate: select department0_.id as id1_1_0_, department0_.person_id as person_i3_1_0_, department0_.name as name2_1_0_, department0_1_.department_id as departme1_2_0_, person1_.id as id1_3_1_, person1_.address_id as address_3_3_1_, person1_.name as name2_3_1_, address2_.id as id1_0_2_, address2_.name as name2_0_2_, address3_.id as id1_0_3_, address3_.name as name2_0_3_ from department department0_ left outer join department_address department0_1_ on department0_.id=department0_1_.address_id left outer join person person1_ on department0_.person_id=person1_.id left outer join Address address2_ on person1_.address_id=address2_.id left outer join Address address3_ on department0_1_.department_id=address3_.id where department0_.id=?
@JoinTable注解用于指定many-to-manytable关系的映射。在这种情况下使用@ManyToMany
左外连接地址 address3_ on department0_1_.department_id=address3_.id whe
可能我看错了,deparment id和address id不匹配。必须是 deparment0_1.address_id = address3_.id
能否尝试将 inversecolumn 更改为 address_id
joinColumns = @JoinColumn(name = "deparment_id", referencedColumnName = "id"),
inverseJoinColumns = @JoinColumn(name = "address_id", referencedColumnName = "id"))
private Address address
joinColumns:分配与实体(在您的案例中为部门)相关的第三个table 列。 inverseJoinColumns:分配第三列table与关联实体(您的情况下的地址)相关。
你的反了。您在 inverseJoinColumns 中拥有实体(部门),在 joinColumns
中拥有地址