JPA 查询未返回预期的结果集
JPA query not returning expected result set
在我工作的一个项目中,我们有一个带有多个实体的持久性单元的 ejb,但最近我们必须更新一些具有复杂 ID(2 个字段组成该 ID)的实体,并且通过此更改,查询不会以我们期望的方式行事。
我们有这个实体对应于一个中间体 table,其中一个实体发生了多对一的关系。
publicic class BapeConvCateZonas implements Serializable {
private static final long serialVersionUID = 1L;
@Size(max = 1)
@Column(name = "B_INTERINIDAD")
private String bInterinidad;
@Size(max = 1)
@Column(name = "B_SUSTIT_LARGA")
private String bSustitLarga;
@Size(max = 1)
@Column(name = "B_SUSTIT_CORTA")
private String bSustitCorta;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "C_CODIGO")
private Long cCodigo;
@JoinColumns({
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_COD_GSA", updatable=false,insertable=false),
@JoinColumn(name = "C_COD_CENTRO", referencedColumnName = "C_CODIGO", updatable=false,insertable=false)})
@ManyToOne
private BapeCentrossanitarios bapeCentrossanitarios;
@JoinColumns({
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_COD_CONV"),
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_COD_CATE")})
@ManyToOne(optional = false)
private BapeConvCateTopes bapeConvCateTopes;
@JoinColumns({
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_COD_GSA", updatable=false,insertable=false),
@JoinColumn(name = "C_COD_CENTRO", referencedColumnName = "C_COD_CENTRO", updatable=false,insertable=false),
@JoinColumn(name = "C_COD_DEPTO", referencedColumnName = "C_CODIGO", updatable=false,insertable=false)})
@ManyToOne
private BapeDeptSanitarios bapeDeptSanitarios;
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_CODIGO", updatable=false,insertable=false)
@ManyToOne
private BapeGerenciasaludarea cCodGsa;
并且实体发生了变化:
public class BapeCentrossanitarios implements Serializable {
@OneToMany(mappedBy = "bapeCentrossanitarios")
private List<BapeConvCateZonas> bapeConvCateZonasList;
private static final long serialVersionUID = 1L;
@EmbeddedId
protected BapeCentrossanitariosPK bapeCentrossanitariosPK;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 150)
@Column(name = "A_DESCRIPCION")
private String aDescripcion;
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_CODIGO", insertable = false, updatable = false)
@ManyToOne(optional = false)
private BapeGerenciasaludarea bapeGerenciasaludarea;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "bapeCentrossanitarios")
private List<BapeDeptSanitarios> bapeDeptSanitariosList;
此实体中的 ID 更改自:
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
@Column(name = "C_CODIGO")
private String cCodigo;
收件人:
@EmbeddedId
protected BapeCentrossanitariosPK bapeCentrossanitariosPK;
并且:
@Embeddable
public class BapeCentrossanitariosPK 实现序列化 {
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
@Column(name = "C_CODIGO")
private String cCodigo;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
@Column(name = "C_COD_GSA")
private String cCodGsa;
当我执行这个查询时 returns 没有任何东西:
SQL: select u from BapeConvCateZonas u where u.bapeConvCateTopes.bapeConvCateTopesPK.cCodConv=:convocatoria and u.bapeConvCateTopes.bapeConvCateTopesPK.cCodCate=:categoria and u.bapeCentrossanitarios is null and u.bInterinidad='S' order by u.cCodGsa.cCodigo ASC;
BapeConvCateTopes 实体:
public class BapeConvCateTopes 实现序列化 {
@Column(name = "N_ANIO_FINALIZACION")
private Short nAnioFinalizacion;
@JoinTable(name = "BAPE_CONV_CATE_MERI_SUB", joinColumns = {
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_COD_CONV"),
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_COD_CATE")}, inverseJoinColumns = {
@JoinColumn(name = "C_COD_AREA", referencedColumnName = "C_COD_AREA"),
@JoinColumn(name = "C_COD_TIPO", referencedColumnName = "C_COD_TIPO"),
@JoinColumn(name = "C_COD_SUBTIPO", referencedColumnName = "C_CODIGO")})
@ManyToMany
@OrderBy("bapeMeritosSubtiposPK.cCodArea ASC")
private List<BapeMeritosSubtipos> bapeMeritosSubtiposList;
@JoinTable(name = "BAPE_CONV_CATE_TITU_EXPE", joinColumns = {
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_COD_CONV"),
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_COD_CATE")}, inverseJoinColumns = {
@JoinColumn(name = "C_COD_TITU", referencedColumnName = "C_CODIGO")})
@ManyToMany
private List<BapeTitulaExper> bapeTitulaExperCollection;
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_CODIGO", insertable = false, updatable = false)
@ManyToOne(optional = false)
private BapeConvocatorias bapeConvocatorias;
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_CODIGO", insertable = false, updatable = false)
@ManyToOne(optional = false)
private BapeCategorias bapeCategorias;
private static final long serialVersionUID = 1L;
@EmbeddedId
protected BapeConvCateTopesPK bapeConvCateTopesPK;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "B_ACTIVO")
private String bActivo;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "B_NOTIF_AUTOMATICA")
private String bNotifAutomatica;
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Column(name = "TOPE")
private BigDecimal tope;
@OneToMany(cascade = CascadeType.REFRESH, mappedBy = "bapeConvCateTopes")
@OrderColumn(name="C_COD_GSA")
private List<BapeConvCateZonas> bapeConvCateZonasList;
和 BapeConvCateTopesPK:
@Embeddable
public class BapeConvCateTopesPK implements Serializable {
@Basic(optional = false)
@NotNull
@Column(name = "C_COD_CONV")
private long cCodConv;
@Basic(optional = false)
@NotNull
@Column(name = "C_COD_CATE")
private long cCodCate;
table 有符合条件的值。
根据上次更改,它必须与关系和复杂 ID 相关,但我不放弃掌握可能是什么。编辑:添加了更多关于 ID 更改的信息。
虽然您的 ID 更改混淆了问题,但使用的 JPQL 不正确。具体来说,“u.bapeCentrossanitarios 为空”强制对表进行内部联接。由于内部联接会过滤掉空值,因此该子句永远不会为真,因此不会返回任何结果。
查询应该对此关系使用左外连接。类似于:
"select u from BapeConvCateZonas u left outer join u.bapeCentrossanitarios bapeCentrossanitarios where u.bapeConvCateTopes.bapeConvCateTopesPK.cCodConv=:convocatoria and u.bapeConvCateTopes.bapeConvCateTopesPK.cCodCate=:categoria and bapeCentrossanitarios is null and u.bInterinidad='S' order by u.cCodGsa.cCodigo ASC"
会起作用,尽管可能有很多方法可以形成类似的查询。
它可能首先起作用的原因是您对复合 PK 的更改可能会绕过 EclipseLink 优化,该优化允许它在不执行连接的情况下评估 'u.bapeCentrossanitarios is Null' - 它可以只检查 pk 值,如果它是空的。随着变化,一个或多个外键可能为空,也可能不为空(它们不受映射控制),因此它必须连接表才能确定。
在我工作的一个项目中,我们有一个带有多个实体的持久性单元的 ejb,但最近我们必须更新一些具有复杂 ID(2 个字段组成该 ID)的实体,并且通过此更改,查询不会以我们期望的方式行事。 我们有这个实体对应于一个中间体 table,其中一个实体发生了多对一的关系。
publicic class BapeConvCateZonas implements Serializable {
private static final long serialVersionUID = 1L;
@Size(max = 1)
@Column(name = "B_INTERINIDAD")
private String bInterinidad;
@Size(max = 1)
@Column(name = "B_SUSTIT_LARGA")
private String bSustitLarga;
@Size(max = 1)
@Column(name = "B_SUSTIT_CORTA")
private String bSustitCorta;
@Id
@Basic(optional = false)
@NotNull
@Column(name = "C_CODIGO")
private Long cCodigo;
@JoinColumns({
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_COD_GSA", updatable=false,insertable=false),
@JoinColumn(name = "C_COD_CENTRO", referencedColumnName = "C_CODIGO", updatable=false,insertable=false)})
@ManyToOne
private BapeCentrossanitarios bapeCentrossanitarios;
@JoinColumns({
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_COD_CONV"),
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_COD_CATE")})
@ManyToOne(optional = false)
private BapeConvCateTopes bapeConvCateTopes;
@JoinColumns({
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_COD_GSA", updatable=false,insertable=false),
@JoinColumn(name = "C_COD_CENTRO", referencedColumnName = "C_COD_CENTRO", updatable=false,insertable=false),
@JoinColumn(name = "C_COD_DEPTO", referencedColumnName = "C_CODIGO", updatable=false,insertable=false)})
@ManyToOne
private BapeDeptSanitarios bapeDeptSanitarios;
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_CODIGO", updatable=false,insertable=false)
@ManyToOne
private BapeGerenciasaludarea cCodGsa;
并且实体发生了变化:
public class BapeCentrossanitarios implements Serializable {
@OneToMany(mappedBy = "bapeCentrossanitarios")
private List<BapeConvCateZonas> bapeConvCateZonasList;
private static final long serialVersionUID = 1L;
@EmbeddedId
protected BapeCentrossanitariosPK bapeCentrossanitariosPK;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 150)
@Column(name = "A_DESCRIPCION")
private String aDescripcion;
@JoinColumn(name = "C_COD_GSA", referencedColumnName = "C_CODIGO", insertable = false, updatable = false)
@ManyToOne(optional = false)
private BapeGerenciasaludarea bapeGerenciasaludarea;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "bapeCentrossanitarios")
private List<BapeDeptSanitarios> bapeDeptSanitariosList;
此实体中的 ID 更改自:
@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
@Column(name = "C_CODIGO")
private String cCodigo;
收件人:
@EmbeddedId
protected BapeCentrossanitariosPK bapeCentrossanitariosPK;
并且:
@Embeddable
public class BapeCentrossanitariosPK 实现序列化 {
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
@Column(name = "C_CODIGO")
private String cCodigo;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
@Column(name = "C_COD_GSA")
private String cCodGsa;
当我执行这个查询时 returns 没有任何东西:
SQL: select u from BapeConvCateZonas u where u.bapeConvCateTopes.bapeConvCateTopesPK.cCodConv=:convocatoria and u.bapeConvCateTopes.bapeConvCateTopesPK.cCodCate=:categoria and u.bapeCentrossanitarios is null and u.bInterinidad='S' order by u.cCodGsa.cCodigo ASC;
BapeConvCateTopes 实体: public class BapeConvCateTopes 实现序列化 {
@Column(name = "N_ANIO_FINALIZACION")
private Short nAnioFinalizacion;
@JoinTable(name = "BAPE_CONV_CATE_MERI_SUB", joinColumns = {
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_COD_CONV"),
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_COD_CATE")}, inverseJoinColumns = {
@JoinColumn(name = "C_COD_AREA", referencedColumnName = "C_COD_AREA"),
@JoinColumn(name = "C_COD_TIPO", referencedColumnName = "C_COD_TIPO"),
@JoinColumn(name = "C_COD_SUBTIPO", referencedColumnName = "C_CODIGO")})
@ManyToMany
@OrderBy("bapeMeritosSubtiposPK.cCodArea ASC")
private List<BapeMeritosSubtipos> bapeMeritosSubtiposList;
@JoinTable(name = "BAPE_CONV_CATE_TITU_EXPE", joinColumns = {
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_COD_CONV"),
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_COD_CATE")}, inverseJoinColumns = {
@JoinColumn(name = "C_COD_TITU", referencedColumnName = "C_CODIGO")})
@ManyToMany
private List<BapeTitulaExper> bapeTitulaExperCollection;
@JoinColumn(name = "C_COD_CONV", referencedColumnName = "C_CODIGO", insertable = false, updatable = false)
@ManyToOne(optional = false)
private BapeConvocatorias bapeConvocatorias;
@JoinColumn(name = "C_COD_CATE", referencedColumnName = "C_CODIGO", insertable = false, updatable = false)
@ManyToOne(optional = false)
private BapeCategorias bapeCategorias;
private static final long serialVersionUID = 1L;
@EmbeddedId
protected BapeConvCateTopesPK bapeConvCateTopesPK;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "B_ACTIVO")
private String bActivo;
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 1)
@Column(name = "B_NOTIF_AUTOMATICA")
private String bNotifAutomatica;
// @Max(value=?) @Min(value=?)//if you know range of your decimal fields consider using these annotations to enforce field validation
@Column(name = "TOPE")
private BigDecimal tope;
@OneToMany(cascade = CascadeType.REFRESH, mappedBy = "bapeConvCateTopes")
@OrderColumn(name="C_COD_GSA")
private List<BapeConvCateZonas> bapeConvCateZonasList;
和 BapeConvCateTopesPK:
@Embeddable
public class BapeConvCateTopesPK implements Serializable {
@Basic(optional = false)
@NotNull
@Column(name = "C_COD_CONV")
private long cCodConv;
@Basic(optional = false)
@NotNull
@Column(name = "C_COD_CATE")
private long cCodCate;
table 有符合条件的值。 根据上次更改,它必须与关系和复杂 ID 相关,但我不放弃掌握可能是什么。编辑:添加了更多关于 ID 更改的信息。
虽然您的 ID 更改混淆了问题,但使用的 JPQL 不正确。具体来说,“u.bapeCentrossanitarios 为空”强制对表进行内部联接。由于内部联接会过滤掉空值,因此该子句永远不会为真,因此不会返回任何结果。
查询应该对此关系使用左外连接。类似于:
"select u from BapeConvCateZonas u left outer join u.bapeCentrossanitarios bapeCentrossanitarios where u.bapeConvCateTopes.bapeConvCateTopesPK.cCodConv=:convocatoria and u.bapeConvCateTopes.bapeConvCateTopesPK.cCodCate=:categoria and bapeCentrossanitarios is null and u.bInterinidad='S' order by u.cCodGsa.cCodigo ASC"
会起作用,尽管可能有很多方法可以形成类似的查询。
它可能首先起作用的原因是您对复合 PK 的更改可能会绕过 EclipseLink 优化,该优化允许它在不执行连接的情况下评估 'u.bapeCentrossanitarios is Null' - 它可以只检查 pk 值,如果它是空的。随着变化,一个或多个外键可能为空,也可能不为空(它们不受映射控制),因此它必须连接表才能确定。