如何使用本机查询在JPA中执行嵌套Join



我有现有的表student,extras&具有此结构的地址

Table student
------------------------------------------
id  |   name    
------------------------------------------
1   | John          
------------------------------------------
Table extras
-----------------------------------------------------------------
id  |   student_id  |  extras_key               | extras_value
-----------------------------------------------------------------
1   | 1             | class                     | X3
2   | 1             | address_id                | addr-2
-----------------------------------------------------------------
Table address
--------------------------------------------
addr_id     |   name            | city
--------------------------------------------
addr-2      | Office            | San Jose
--------------------------------------------

如何在JPA-Hibernate上加入这些表?我当前的代码是

学生实体类

@Entity
@Table(name = "student")
@Data
public class Student implements Serializable {
private static final long serialVersionUID = 1L;
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "id", nullable = false)
private Integer id;
@Column(name = "name", nullable = false, columnDefinition = "TEXT")
private String name;
//    @OneToOne
//    @JoinColumn(name = "id", referencedColumnName = "student_id")
//    private Extras extras;
@OneToMany(mappedBy = "studentId")
private Set<Extras> extras;
}

Extras实体类:

@Data
@Entity
@Table(name="extras")
public class Extras implements Serializable {
@Id
@Column(name="id")
private int id;
@Column(name="student_id", nullable = false)
private int studentId;
@Column(name="extras_key", nullable = false)
private String extrasKey;
@Column(name="extras_value", nullable = false)
private String extrasValue;
@OneToOne(optional = false)
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "extras_value", referencedColumnName = "addr_id", insertable = false, updatable = false)
private Address address;
}

和地址实体类

@Entity
@Table(name="address")
@Data
public class Address implements Serializable {
@Id
@Column(name="addr_id")
private String addrId;
@Column(name="name")
private String name;
@Column(name="city")
private String city;
}

这是我的存储库类

@Repository
public interface StudentRepository extends CrudRepository<Student, Integer> {
@Query(value = "select * from student " +
"JOIN extras ON student.id=extras.student_id " +
"JOIN address ON address.addr_id = extras.extras_value", nativeQuery = true)
List<Student> findAllData();
}

但当我在学生实体中使用OneToMany时,我得到了Exception"org.hibernate.LazyInitializationException:未能延迟初始化角色集合:com.jpa.belajarjpa.enitities.Student.extras,无法初始化代理-无会话">。但是当我在Student Entity中使用OneToOne时,我没有遇到异常,但得到了错误的结果,Student(id=1,name=john,extras=null(,当我执行这个查询时,它显示了正确的结果选择*FROM student加入student.id=extras.student_id加入address.addr_id=extras.extras_value

您需要将连接获取与HQL查询一起使用,如下所示:

@Repository
public interface StudentRepository extends CrudRepository<Student, Integer> {
@Query("FROM Student s " +
"JOIN FETCH s.extras e " +
"JOIN FETCH e.address")
List<Student> findAllData();
}

CCD_ 1是反模式。如果我是你,我就不会用它。

通过在属性中添加spring.jpa.properties.hibernate.enable_lazy_load_no_trans=true解决

最新更新