简体   繁体   中英

JPA query not returning expected result set

In a project i'm working we have an ejb with a persistence unit with multiple entitys but recently we have to update some entities with a complex id (2 fields forming that id) and with this change a query does not behave in the way we expect. We have this entity who correspond to an intermediate table with a relationship many to one with one of the entities changed.

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;

And the entity changed:

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;

The id in this entity changed from:

@Id
@Basic(optional = false)
@NotNull
@Size(min = 1, max = 4)
@Column(name = "C_CODIGO")
private String cCodigo;

To:

@EmbeddedId
protected BapeCentrossanitariosPK bapeCentrossanitariosPK;

And:

@Embeddable

public class BapeCentrossanitariosPK implements Serializable {

@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;

And when I execute this query does not returns anything:

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 entity: public class BapeConvCateTopes implements Serializable {

    @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;

And 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;

The table has values that meet the criteria. Based on the last change it has to be something related to the relationship and the complex id but i don't quit grasp what could be. Edit: Added a little more information about the ID change.

While your ID changes confound the issue, the JPQL being used is incorrect. Specifically the " u.bapeCentrossanitarios is null" is forcing an inner join over the tables. As an inner join filters out nulls, this clause can never be true, and so no results are returned.

The query should use a left outer join over this relationship. Something like:

"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"

Will work, though there might be many ways to form a similar query.

The reason it might have worked first is that your changes to a compound PK are likely bypassing an EclipseLink optimization that allows it to evaluate the 'u.bapeCentrossanitarios is Null' without peforming the join - it could just check the pk value if it was null. With the changes, the one or more of the foreign keys may or may not be null (they are not controlled by the mapping), so it must join the tables to be sure.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM