Problema Hibernate. Entidade que agrega ela mesma

Estou com um problema ao utilizar uma entidade que agrega ela mesma.

Nesse caso, preciso, pois os itens de um pedido podem ser faturados em pedidos diferentes. Por exemplo: Um pedido com codigo 1 tem um item com a quantidade 1000. Mas, a fábrica não conseguirá fabricar tudo em tempo. Então, 500 unidades são faturadas e as outras 500 ficam para outro pedido.

Por isso armazeno dentro do pedido qual foi o pedido que originou ele. (para depois conseguir “agrupar” todos itens em uma venda só - em um relatório).

@Entity
public class Pedido
{

    @ManyToOne
    @JoinColumn(name="origem", referencedColumnName="codigo")
    private Pedido origem;

}

Mas, está acontecendo algo “estranho”.

Exemplo (no banco está correto):
Pedido 001 - Item 001 - Qtd 500 - Referencia AAA - Origem NULL
Pedido 002 - Item 002 - Qtd 500 - Referencia AAA - Origem 001

No entanto, se eu faço uma criteria para procurar todos os pedidos que tem como origem o pedido 001. Aparecem três vezes o pedido 002 (no banco o unico pedido que tem como origem o 001 é o pedido 002).

E isso acontece em diversos testes. Porém, não em todos.

Será que pode estar acontecendo alguma confusão na árvore de objetos do Hibernate? Estou fazendo algo errado?

Tenta fazer isso

@Entity  
public class Pedido  
{  
  
    @ManyToOne  
    @JoinColumn(name="origem", referencedColumnName="codigo")  
    private Pedido origem;  
   
    @OneToMany(mappedBy = "origem")
    private List<Pedido> pedidos
  
}  

Não adiantou. Tenho outras situações que utilizo o ManyToOne unidirecional e nunca tive problemas.

O que me intrigou é que os dados estão corretos no banco de dados. Se eu fizer uma query SQL ou HQL retorna os pedidos corretamente, mas na Criteria retorna 3~4 vezes o mesmo pedido na “lista”.

Muito provavelmente é um bug do Criteria do Hibernate:

DetachedCriteria criteria = DetachedCriteria.forClass(Pedido.class); criteria.add(Restrictions.eq("pedidoDeOrigem.ped_codigo", pedidoDeOrigem.getPed_codigo())); System.out.println("Criteria: " + pedidos.pesquisarCriteria(id, criteria).size());

Output: 4

String hql = "SELECT ped_codigo FROM Pedido WHERE pedidoDeOrigem.ped_codigo = :origem ORDER BY ped_data_emissao"; System.out.println("HQL: " + pedidos.pesquisarHQL(id, hql, new Parametro[]{new Parametro("origem", pedidoDeOrigem.getPed_codigo())}).size());

Output: 1