Join multiple fetch returning duplicate JPA Criteria API values

1

In the method in question I want to return the query with the joins of employee and company. However, the Company class is related to the Query and to the Employee, and is returning duplicate in the JSON.

Query class

@Entity
@Table(name="CONSULTA")
public class Consulta implements Serializable {
private static final long serialVersionUID = 1L;

@Id
private long id;

@Column(name="IDEMPRESA")
private Long idEmpresa;

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="IDEMPRESA", referencedColumnName = "ID", 
insertable=false, updatable=false)
private Empresa empresa;

@Column(name="IDEMPREGADO")
private Long idEmpregado;

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumns({
    @JoinColumn(name="IDEMPRESA", referencedColumnName="EMPRESA", insertable=false, updatable=false),
    @JoinColumn(name="IDEMPREGADO", referencedColumnName="ID", insertable=false, updatable=false)
})
private Empregado empregado;

/* Getters e Setter */
}

Business Class

@Entity
@Table(name="EMPRESAS")
public class Empresa implements Serializable {
private static final long serialVersionUID = 1L;

@Id
private Long id;

@Column(name="CIDADE")
private Long idCidade;

@ManyToOne(fetch=FetchType.LAZY)
@JoinColumn(name="CIDADE", referencedColumnName = "ID", insertable=false, updatable=false)
private Cidade cidade;

@Column(name="RAZAOSOCIAL")
private String razaoSocial;

private String denominacao;

private String cnpj;

private String ddd;

private String fone;

private Character status;

private Long usuario;

/* Getters e Setter */
}

Employee Class

@Entity
@Table(name="EMPREGADOS")
public class Empregado implements Serializable {
private static final long serialVersionUID = 1L;

@EmbeddedId
private EmpregadoPK id;

@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "EMPRESA", referencedColumnName = "ID", insertable = false, updatable = false)
private Empresa empresa;

private String nome;

/* Getters e Setters */

}

Method with fetch

public Consulta getById(Long id) {
    CriteriaBuilder cb = em.getCriteriaBuilder();
    CriteriaQuery<Consulta> cq = cb.createQuery(Consulta.class);
    Root<Consulta> consulta = cq.from(Consulta.class);

    List<Predicate> predicates = new ArrayList<Predicate>();

    predicates.add(cb.equal(consulta.<Long>get("id"), id));

    cq.distinct(true);

    consulta.fetch("empresa");
    consulta.fetch("empregado");

    cq.select(consulta).where(predicates.toArray(new Predicate[]{}));

    TypedQuery<Consulta> tquery = em.createQuery(cq);
    tquery.setMaxResults(1);

    return tquery.getSingleResult();
}

Return JSON

{
"id": 1268,
"data": "2018-03-27",
"hora": "01/01/1970 09:00:00",
"descricao": null,
"idEmpresa": 1,
"empresa": {
    "id": 1,
    "razaoSocial": "Demonstração LTDA"
},
"idEmpregado": 45,
"empregado": {
    "id": {
        "idEmpresa": 1,
        "id": 45
    },
    "empresa": {
        "id": 1,
        "razaoSocial": "Demonstração LTDA"
    },
    "nome": " ANA MARIA COSTA PORTO",
    "admissao": "2017-09-13",
    "demissao": null,
    "nascimento": "1966-11-17",
    "sexo": "M",
    "matricula": "65989898"
},
"status": "1"
}
    
asked by anonymous 04.04.2018 / 20:44

1 answer

0

The simplest way to avoid repeating information about the Empresa entity (since I do not know your data model) would be to use the @JsonIgnoreProperties feature in the Empregado class, including the empresa , as illustrated below:

@JsonIgnoreProperties(value = { "empresa" })
@Entity
@Table(name="EMPREGADOS")
public class Empregado implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private EmpregadoPK id;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "EMPRESA", referencedColumnName = "ID", insertable = false, updatable = false)
    private Empresa empresa;

    private String nome;

    /* Getters e Setters */

}

It is possible to make use of the mechanism to ignore an attribute of a class when it will undergo serialization for JSON in other ways (using @JsonIgnore , for example), but I prefer to use it in this way. used in the example for ease of reading the code and also for future inclusion and / or removal of attributes for JSON.

Now a question about your data model: What is the motivator of the Consulta class relating to both Empregado and Empresa ? Note that only the relationship with class Empregado would be enough to get all the information in your JSON.

    
05.04.2018 / 04:06