提问者:小点点

JavaSpring JPA参考,只从连接表返回一个结果


我相信下面的代码工作正常,但我的逻辑有缺陷,所以我正在寻求帮助以获得我真正想要的结果。此外,我认为我对JPA方法的尝试过于复杂,可能有更干净的解决方案。我知道我可能会使用@Query,但我想尝试让方法名解决方案也正常工作,这样我就可以了解我哪里出错了。

为了简单起见,我在本例中剥离了DB表,但是我有表1,它是顶级表,表2位于它下面,有一个外键返回到表1。

表1-

不幸的是,我相信通过下面的代码,它可以识别出表2的其中一条记录在所需的日期范围内,因此正在从表1中提取与ID相关的所有记录。但我可能在这一点上错了,逻辑也可能以不同的方式存在缺陷。

任何帮助都将不胜感激。

表1实体类

@Entity
@Table(name = "TABLE1")
public class Table1 {
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false, unique = true)
    private Integer id;
    
    @OneToMany(mappedBy = "table1", fetch = FetchType.EAGER, cascade = CascadeType.ALL)
    @Fetch(value = FetchMode.SUBSELECT)
    @JsonManagedReference
    private List<Table2> table2; 

    //Plus getters & setters

表2实体类

@Entity
@Table(name = "TABLE2")
public class Table2{
    
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "ID", nullable = false, unique = true)
    private Integer id;
    
    @ManyToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "Table1Id")
    @JsonBackReference
    private Table1 table1;
    
    @Column(name = "EffectiveDateTime", nullable = false)
    private LocalDateTime effectiveDateTime;

    //Plus getters & setters

回购类

@Repository
public interface Repository extends JpaRepository<Table1, Integer>, JpaSpecificationExecutor<Table1>  {
    
    public Optional<Table1> findTopByIdAndTable2EffectiveDateTimeLessThanEqualOrderByTable2EffectiveDateTimeDesc(int id, LocalDateTime now);
}

当前JSON返回

{
    "id": 5
    "Table2": [
        {
            "id": 6,
            "effectiveDateTime": "2021-01-01T00:00:01"
        },
        {
            "id": 8,
            "effectiveDateTime": "2022-01-01T00:00:01"
        },
        {
            "id": 9,
            "effectiveDateTime": "2023-01-01T00:00:01"
        }
    ]
}

共1个答案

匿名用户

一旦声明了oneToMany关系,实体将在调用getTable方法时加载所有连接的实体(序列化时jackson会调用该方法)。我相信如果您激活调试模式,您将看到2个请求,第一个是您在repopitory中描述的请求,第二个是JPA用于加载所有相关table2实体的请求。

他们提供了一些可能的方法来实现您的目标:

  • 第一个(也是最明显的?)是手动使2请求等效于您的HQL请求(表1按ID查找,然后是表2按…查找)然后将这两个结果相加
  • 第二种方法是使用jackson以您想要的方式序列化数据(通过过滤无用的表2数据)
  • 第三种方法是使用jackson将table2(提供相应的table1数据)序列化为适当的JSON。如果您的表1引用了大量的表2数据,可能会更加复杂,但效率可能会更高
  • 最后一种方法是尝试使用投影,它允许您在请求数据时仅声明要检索的数据

希望这有帮助!