title: Hibernate Crertira returns duplicates
body: <p>I have a table purchase, with DDL of : </p>
  
  <pre><code>CREATE TABLE purchase
  (
    idpurchase serial NOT NULL,
    code character varying(50),
    date timestamp without time zone,
    totalht double precision,
    tva double precision,
    totalttc double precision,
    CONSTRAINT purchase_pkey PRIMARY KEY (idpurchase)
  )
  </code></pre>
  
  <p>Purchase table has one to many relationship with purchaseproduct, the DDL for purchaseproduct is : </p>
  
  <pre><code>CREATE TABLE purchaseproduct
  (
    idpurchaseproduct serial NOT NULL,
    idpurchase integer,
    idproduct integer,
    qty double precision,
    price double precision,
    CONSTRAINT purchaseproduct_pkey PRIMARY KEY (idpurchaseproduct),
    CONSTRAINT purchaseproduct_idproduct_fkey FOREIGN KEY (idproduct)
        REFERENCES product (idproduct) MATCH SIMPLE
        ON UPDATE NO ACTION ON DELETE NO ACTION,
    CONSTRAINT purchaseproduct_idpurchase_fkey FOREIGN KEY (idpurchase)
        REFERENCES purchase (idpurchase) MATCH SIMPLE
        ON UPDATE NO ACTION ON DELETE NO ACTION
  )
  </code></pre>
  
  <p>Here are my POJOS:</p>
  
  <p>Purchase:
      @Entity
      @Table(name = "purchase")
      @Access(AccessType.PROPERTY)
      public class Purchase {
          private LongProperty idPurchase;
          private StringProperty codePurchase;
          private ObjectProperty datePurchase;
          private DoubleProperty totalHt;
          private DoubleProperty tva;
          private DoubleProperty totalTTC;</p>
  
  <pre><code>    private Set&lt;LineCommand&gt; lineItems = new HashSet&lt;LineCommand&gt;(0);
  
      public Purchase() {
          this.idPurchase = new SimpleLongProperty();
          this.codePurchase = new SimpleStringProperty();
          this.datePurchase = new SimpleObjectProperty&lt;&gt;();
          this.totalHt = new SimpleDoubleProperty();
          this.tva = new SimpleDoubleProperty();
          this.totalTTC = new SimpleDoubleProperty();
  
  
      }
  
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "purchase_seq_gen")
      @SequenceGenerator(name = "purchase_seq_gen", sequenceName = "purchase_idpurchase_seq", initialValue = 1, allocationSize = 1)
      @Column(name = "idpurchase", unique = true, nullable = false)
      public long getIdPurchase() {
          return idPurchase.get();
      }
  
      public LongProperty idPurchaseProperty() {
          return idPurchase;
      }
  
      public void setIdPurchase(long idPurchase) {
          this.idPurchase.set(idPurchase);
      }
  
      @Column(name = "code")
      public String getCodePurchase() {
          return codePurchase.get();
      }
  
      public StringProperty codePurchaseProperty() {
          return codePurchase;
      }
  
      public void setCodePurchase(String codePurchase) {
          this.codePurchase.set(codePurchase);
      }
  
      @Column(name = "date")
      @Convert(converter = LocalDatePersistanceConverter.class)
      public LocalDate getDatePurchase() {
          return datePurchase.get();
      }
  
      public ObjectProperty&lt;LocalDate&gt; datePurchaseProperty() {
          return datePurchase;
      }
  
      public void setDatePurchase(LocalDate datePurchase) {
          this.datePurchase.set(datePurchase);
      }
  
      @Column(name = "totalHt")
      public double getTotalHt() {
          return totalHt.get();
      }
  
      public DoubleProperty totalHtProperty() {
          return totalHt;
      }
  
      public void setTotalHt(double totalHt) {
          this.totalHt.set(totalHt);
      }
  
      @Column(name = "tva")
      public double getTva() {
          return tva.get();
      }
  
      public DoubleProperty tvaProperty() {
          return tva;
      }
  
      public void setTva(double tva) {
          this.tva.set(tva);
      }
  
      @Column(name = "totalTTC")
      public double getTotalTTC() {
          return totalTTC.get();
      }
  
      public DoubleProperty totalTTCProperty() {
          return totalTTC;
      }
  
      public void setTotalTTC(double totalTTC) {
          this.totalTTC.set(totalTTC);
      }
  
  
      @OneToMany(mappedBy = "purchase", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      public Set&lt;LineCommand&gt; getLineItems() {
          return this.lineItems;
      }
  
      public void setLineItems(Set&lt;LineCommand&gt; lineItems) {
          this.lineItems = lineItems;
      }
  
      @Override
      public boolean equals(Object obj) {
          if (obj == null) {
              return false;
          } else {
  
              if (this.idPurchase.getValue() == ((Purchase) obj).getIdPurchase())
                  return true;
              else
                  return false;
          }
      }
  
  }
  </code></pre>
  
  <p>LineCommand : </p>
  
  <pre><code>@Entity
  @Table(name = "purchaseProduct")
  @Access(AccessType.PROPERTY)
  public class LineCommand implements Serializable {
  
  
      private LongProperty idPurchaseProduct;
      private Product product;
      private Purchase purchase;
      private DoubleProperty sellPrice = new SimpleDoubleProperty();
      private DoubleProperty qty = new SimpleDoubleProperty();
      private DoubleProperty subTotal = new SimpleDoubleProperty();
  
  
      public LineCommand() {
          this.idPurchaseProduct = new SimpleLongProperty();
          this.product = new Product();
          this.purchase = new Purchase();
  
          this.sellPrice = new SimpleDoubleProperty();
          this.qty = new SimpleDoubleProperty();
          this.subTotal = new SimpleDoubleProperty();
  
          NumberBinding subTotalBinding = Bindings.multiply(this.qty, this.sellPrice);
          subTotal.bind(subTotalBinding);
  
      }
  
      @Id
      @GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "purchase_seq_gen")
      @SequenceGenerator(name = "purchase_seq_gen", sequenceName = "purchaseproduct_idpurchaseproduct_seq", initialValue = 1, allocationSize = 1)
      @Column(name = "idpurchaseproduct ", unique = true, nullable = false)
      public long getIdPurchaseProduct() {
          return idPurchaseProduct.get();
      }
  
      public LongProperty idPurchaseProductProperty() {
          return idPurchaseProduct;
      }
  
      public void setIdPurchaseProduct(long idPurchaseProduct) {
          this.idPurchaseProduct.set(idPurchaseProduct);
      }
  
      @ManyToOne
      @JoinColumn(name = "idproduct")
      public Product getProduct() {
          return product;
      }
  
      public void setProduct(Product product) {
          this.product = product;
      }
  
      @ManyToOne
      @JoinColumn(name = "idpurchase")
      public Purchase getPurchase() {
          return purchase;
      }
  
      public void setPurchase(Purchase purchase) {
          this.purchase = purchase;
      }
  
  
      @Column(name = "price")
      public double getSellPrice() {
          return sellPrice.get();
      }
  
      public DoubleProperty sellPriceProperty() {
          return sellPrice;
      }
  
      public void setSellPrice(double sellPrice) {
          this.sellPrice.set(sellPrice);
      }
  
      @Column(name = "qty")
      public double getQty() {
          return qty.get();
      }
  
      public DoubleProperty qtyProperty() {
          return qty;
      }
  
      public void setQty(double qty) {
          this.qty.set(qty);
      }
  
      @Transient
      public double getSubTotal() {
          return subTotal.get();
      }
  
      public DoubleProperty subTotalProperty() {
          return subTotal;
      }
  
      public void setSubTotal(double subTotal) {
          this.subTotal.set(subTotal);
      }
  
      @Override
      public boolean equals(Object obj) {
          if (obj == null) {
              return false;
          } else {
              Product product = ((LineCommand) obj).getProduct();
              Purchase purchase = ((LineCommand) obj).getPurchase();
  
              if (this.product.equals(product) &amp;&amp; this.purchase.equals(purchase))
                  return true;
              else
                  return false;
          }
      }
  }
  </code></pre>
  
  <p>After getting all purchase result from database, i notice duplicates in purchases with two entries in purchaseproduct table.</p>
  
  <p>Here is the way i retreive the list of purchases from database:</p>
  
  <pre><code>public ObservableList&lt;Purchase&gt; findAllByDate(LocalDate from, LocalDate to) {
          try {
              if (!session.isOpen())
                  session = DatabaseUtil.getSessionFactory().openSession();
              session.beginTransaction();
  
              Criterion ctr1 = Restrictions.le("datePurchase", to);
              Criterion ctr2 = Restrictions.ge("datePurchase", from);
              List&lt;Purchase&gt; resultList = session.createCriteria(Purchase.class).add(Restrictions.and(ctr1, ctr2)).list();
  
              ObservableList&lt;Purchase&gt; list =
                      FXCollections.observableList(resultList);
              session.getTransaction().commit();
              session.close();
              return list;
          } catch (Exception e) {
              e.printStackTrace();
              return null;
          }
      }
  </code></pre>