Onetoone returning wrong value

Asked

Viewed 48 times

2

Guys, help me please, I’ve got a problem here and I’ve been racking my brain trying to figure this out for hours. I use Spring in the project and have the following relationship in one of my models:

@OneToOne()
@JoinColumn(name = "ITE_COD_INTERNO")
@NotFound(action = NotFoundAction.IGNORE)
@Getter @Setter
private ItemPreco preco;

In Itempreco I have this:

@OneToOne(mappedBy = "preco")
@Setter
private Item item;

My Itempreco class has two main fields:

@Id
@Column(name = "TPC_COD_INTERNO")
@Getter @Setter
private String itemId;

@Column(name = "TPC_UNIDADE")
@Getter @Setter
private String unidade;

My Repository that I perform the query is as follows:

@Query("SELECT i FROM Item i "
        + "WHERE i.grupo.visivel = :visivel "
        + "AND i.preco.unidade = :unidade "
        + "AND i.itemId = :itemId "
        + "AND i.preco.preco <> 0 "
        + "ORDER BY i.descricao")
Item findByItemIdAndVisivelAndUnidade(@Param("itemId") String itemId, @Param("visivel") boolean visivel, @Param("unidade") String unidade);

The return I receive is a line from a "random" unit and not the one I sought. Example: I searched for unit 001 and get unit 002.

And what I want is to fetch an item and the price of it, which has a Onetoone relationship if searched by internal code + unit.

If anyone can give me a light on how to resolve this I thank you very much from now on!

  • You’re confused about this. For example: you say that "My Item class has two main fields": Itemid and drive; however in your query you put as if Itemid were in Item (i.itemId:=itemId) and unit in an Item attribute called preco (i.preco.unidade), that wasn’t even shown in your Item class.

  • The two classes have an Itemid attribute to be able to relate to each other. And I think you read wrong the part that said, "My Item class has two main fields," actually I wrote "My Itempreco class has two main fields," maybe that’s why I got confused

  • Still confused. If Itempreco has Item "Mapped by preco" would not need an Itemid to map. I think it’s best to put the complete code of the Item and Itempreco classes.

1 answer

1

Solution found: i created a constructor with attributes for the Item class and instead of using the relationship with the Itempreco table, I only used the value returned from select.

Builder:

    public Item(String itemId, String codBarra, CbAlt codBarraAlterado, Long estado, String complemento, String descricao, String unidade, String pesado, Long opcional, Integer opcionaisGratis,
        String impressoras, String tempoPreparo, GrupoItem grupo, String cardapio, Double precoSelecionado) {
    super();
    this.itemId = itemId;
    this.codBarra = codBarra;
    this.codBarraAlterado = codBarraAlterado;
    this.estado = estado;
    this.complemento = complemento;
    this.descricao = descricao;
    this.unidade = unidade;
    this.pesado = pesado;
    this.opcional = opcional;
    this.opcionaisGratis = opcionaisGratis;
    this.impressoras = impressoras;
    this.tempoPreparo = tempoPreparo;
    this.grupo = grupo;
    this.cardapio = cardapio;
    this.precoSelecionado = precoSelecionado;
}

Then I created an attribute with @Transient in the Item model:

@Transient
@Getter @Setter
private Double precoSelecionado;

And my selection in Itemrepository was like this:

@Query("SELECT new br.com.rp.restaurante.model.Item(i.itemId, i.codBarra, i.codBarraAlterado, i.estado, i.complemento, i.descricao, i.unidade, i.pesado, i.opcional, i.opcionaisGratis, i.impressoras, i.tempoPreparo, i.grupo, i.cardapio, i.preco.preco) FROM Item i "
        + "WHERE ((i.codBarra LIKE %:codBarra%) OR (i.itemId LIKE %:itemId%) OR (lower(i.descricao) LIKE concat('%', lower(:descricao), '%') )) "
        + "AND i.grupo.visivel = :visivel "
        + "AND i.preco.unidade = :unidade "
        + "AND i.preco.preco <> 0 "
        + "ORDER BY i.descricao")
List<Item> findByItemIdContainingOrCodBarraContainingOrDescricaoContainingAllIgnoreCaseAndGrupo_VisivelTrueOrderByDescricao(@Param("itemId") String itemId, @Param("codBarra") String codBarra, @Param("descricao") String descricao, @Param("visivel") boolean visivel, @Param("unidade") String unidade);

This way, I get the correct value returned from select and step to the @Transient attribute of the Item class and use it.

What was happening before was that I was not linking myself that after the select, regardless of the parameterization, the relationship that was considered and not what I used in the select, then he created an object with the proper relationships. And as the Itempreco table had two attributes that should be considered at the time of the relationship (unit/product id), what did not happen, because the relationship considered only the product id (obvious) and the unit was left out, this entailed a return of the first line of select, which could be the price of any unit.

Browser other questions tagged

You are not signed in. Login or sign up in order to post.