【问题标题】:Filtering out nested objects in JPA query过滤掉 JPA 查询中的嵌套对象
【发布时间】:2020-08-05 13:50:02
【问题描述】:

我正在努力过滤我的 JPA 存储库查询中的第三级嵌套对象。

我有以下对象,我想在其中接收所有 id = 5 的旅程一部分的舞会,并且只接收来自 id = 12 的用户的 promMeasurement 对象。

proms: [
  {
    id: 1,
    name: "test",
    journeys: [
      {
        id: 5
      },
      {
        id: 6
      },
    ]
    promMeasurements: [
      {
        id: 101,
        value: 6,
        user: {
          id: 12
        }
      },
      {
        id: 102,
        value: 2,
        user: {
          id: 13
        }
      },
      {
        id: 103,
        value: 8,
        user: {
          id: 14
        }
      },
    ]
  },
  {
    id: 2,
    name: "test 2",
    journeys: [
      {
        id: 5
      },
      {
        id: 6
      },
    ]
    promMeasurements: [
      {
        id: 223,
        value: 1,
        user: {
          id: 12
        }
      },
      {
        id: 224,
        value: 5,
        user: {
          id: 13
        }
      },
      {
        id: 225,
        value: 3,
        user: {
          id: 14
        }
      },
    ]
  },
  {
    id: 3,
    name: "test 3",
    journeys: [
      {
        id: 7
      }
    ]
    promMeasurements: [
      {
        id: 223,
        value: 1,
        user: {
          id: 26
        }
      },
      {
        id: 224,
        value: 5,
        user: {
          id: 33
        }
      },
      {
        id: 225,
        value: 3,
        user: {
          id: 4
        }
      },
    ]
  }
]

所以这一切的结果将是最终得到以下对象:

proms: [
  {
    id: 1,
    name: "test",
    journeys: [
      {
        id: 5
      }
    ]
    promMeasurements: [
      {
        id: 101,
        value: 6,
        user: {
          id: 12
        }
      }
    ]
  },
  {
    id: 2,
    name: "test 2",
    journeys: [
      {
        id: 5
      }
    ]
    promMeasurements: [
      {
        id: 223,
        value: 1,
        user: {
          id: 12
        }
      }
    ]
  }
]

现在,我已经能够使用此查询对旅程进行过滤:

List<Prom> findAllByJourneysId(Long id);

但过滤 promMeasurements 尚未成功。 我尝试过的一些例子。但这些不起作用,因为它们只返回与上述查询相同的结果。

List<Prom> findAllByJourneysIdAndPromMeasurements_Patient_Id(Long journeyId, Long patientId);
List<Prom> findAllByJourneysIdAndPromMeasurementsPatientId(Long journeyId, Long patientId);

上一个函数的查询日志:

[DEBUG] 2020-08-06 10:57:56.028 [qtp1976725830-44] SQL - select prom0_.id as id1_38_, prom0_.createdAt as createdA2_38_, prom0_.updatedAt as updatedA3_38_, prom0_.name as name4_38_, prom0_.threshold as threshol5_38_ from prom prom0_ left outer join prom_journey journeys1_ on prom0_.id=journeys1_.prom_id left outer join journey journey2_ on journeys1_.journey_id=journey2_.id left outer join prommeasurement prommeasur3_ on prom0_.id=prommeasur3_.prom_id left outer join user user4_ on prommeasur3_.patient_id=user4_.id left outer join user_address user4_1_ on user4_.id=user4_1_.user_id where journey2_.id=? and user4_.id=?

当我手动执行这个函数时,我得到以下结果。 如您所见,每个“舞会”都显示了两次,这已经不正确了。

谁能帮我解决这个问题?

实体:

public class Prom extends DateAudit {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  private String name;

  @ManyToMany(fetch = FetchType.LAZY)
  @JoinTable(name = "prom_journey", joinColumns = @JoinColumn(name = "prom_id"),
        inverseJoinColumns = @JoinColumn(name = "journey_id"))
  @JsonBackReference(value = "prom-journeys")
  private Set<Journey> journeys = new HashSet<>();

  @OneToMany(mappedBy = "prom")
  @JsonManagedReference(value = "prom-prom-measurements")
  private List<PromMeasurement> promMeasurements;
}

public class PromMeasurement extends DateAudit {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;

  @ManyToOne(fetch = FetchType.EAGER)
  @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })    
  @JsonBackReference(value = "prom-prom-measurements")
  private Prom prom;

  @ManyToOne(fetch = FetchType.LAZY)
  @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
  @JsonBackReference(value = "patient-prom-measurements")
  private User patient;

  @ManyToOne(fetch = FetchType.LAZY)
  @JsonIgnoreProperties({ "hibernateLazyInitializer", "handler" })
  @JsonBackReference(value = "journey-prom-measurements")
  private Journey journey;

  private Integer value;
}

public class User extends DateAudit {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
}

public class Journey extends DateAudit {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
}

【问题讨论】:

  • 你有什么异常吗?
  • 不,只是收到与查询 findAllByJourneysId 相同的结果。
  • 好的,可以添加实体定义吗
  • 我添加了它们:)
  • 可以添加执行查询日志吗?

标签: java spring-boot jpa spring-data-jpa


【解决方案1】:

你可以用@Query注解试试

@Query(value = "SELECT distinct p FROM Prom p JOIN FETCH p.journeys pj JOIN FETCH p.promMeasurements pp JOIN FETCH pp.patient ppp WHERE pj.id = :journeyId AND ppp.id = :patientId")

列出 findDistinctByJourneysIdAndPromMeasurementsPatientId(Long JourneyId, Long patientId);

【讨论】:

    【解决方案2】:

    不确定您使用的是哪个版本的 spring-boot,但从版本 2.x 开始,下划线是不必要的。

    问题可能在于您混合了两个下划线:

    PromMeasurements_Patient_Id
    

    查询的部分没有下划线:

    findAllByJourneysId
    

    尽量保持查询语言使用的一致性。

    【讨论】:

    • 好的,感谢您澄清这部分,但不幸的是,省略下划线并不能解决问题。另外,当我将鼠标悬停在该方法上时,它会显示以下内容:“预期参数类型:Journey, PromMeasurement”
    猜你喜欢
    • 1970-01-01
    • 2021-08-01
    • 2016-05-05
    • 2020-11-01
    • 1970-01-01
    • 2011-12-24
    • 1970-01-01
    • 2018-08-08
    • 2018-07-09
    相关资源
    最近更新 更多