有人可以建议我如何处理这些实体的equals和hashCode方法?

这是Gara(竞赛)和Agenzia(代理机构)之间的多对多关系:
一个竞赛可以有多个代理,一个代理可以参加更多竞赛。

我尝试了一些实现,但还是收到Stackoverflow错误,或者,
当我更新Gara(竞赛)时,我无法更新Agenzie(代理商)的集合,因为出现此错误:


  org.springframework.dao.DuplicateKeyException:与另一个对象
  相同的标识符值已与该会话关联:
  [com.myApp.model.GaraAgenzia#com.mmyApp.model.GaraAgenziaId@49f];
  嵌套的异常是org.hibernate.NonUniqueObjectException:
  具有相同标识符值的不同对象已被关联
  与会话:
  [com.myApp.model.GaraAgenzia#com.myApp.model.GaraAgenziaId@49f]


当我尝试进行更新时。

谢谢

Gare.java:

@Entity
@Table(name = "gare")
public class Gara extends BaseEntity implements Serializable {

    private static final long serialVersionUID = 6395640401966812691L;


    /*
     * inizializzo logger
     */
    static Logger logger = LoggerFactory.getLogger(Gara.class);


    /*
     * molti a molti gara-agenzia
     *
     * EAGER altrimenti da errore:  could not initialize proxy - no Session
     */
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.gara", cascade=CascadeType.ALL, orphanRemoval=true)
    private Set<GaraAgenzia> garaAgenzie = new HashSet<GaraAgenzia>(0);



    /*
     * molti a molti gara-servizi
     *
     * EAGER altrimenti da errore:  could not initialize proxy - no Session
     */
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "pk.gara", cascade=CascadeType.ALL, orphanRemoval=true)
    private Set<GaraServizio> garaServizi = new HashSet<GaraServizio>(0);


    /*
     *
     * colonna TITOLO
     *
     */
   @NotNull(message = "Il campo TITOLO è obbligatorio")
   @NotEmpty(message = "Il campo TITOLO è obbligatorio")
   @Size(min = 0, max = 255, message = "Lunghezza massima campo TITOLO: 255 caratteri")
   @Column(name = "TITOLO", length = 255)
   private String titolo;





    /*
     *
     * colonna OBIETTIVO
     *
     */
    @NotNull(message = "Il campo OBIETTIVO è obbligatorio")
    @Min(value = 1, message = "Il campo OBIETTIVO deve essere maggiore di ZERO")
    @Column(name = "OBIETTIVO")
    private int obiettivo = 0;


    /*
     *
     * colonna BONUS
     *
     */
    @NotNull(message = "Il campo BONUS è obbligatorio")
    @Min(value = 1, message = "Il campo BONUS deve essere maggiore di UNO")
    @Column(name = "BONUS")
    private float bonus = 0f;

     @Column(name = "data_iniziale", nullable = false)
     private Date dataIniziale;

     @Column(name = "data_finale", nullable = false)
     private Date dataFinale;


    public Set<GaraAgenzia> getGaraAgenzie() {
        return garaAgenzie;
    }

    public void setGaraAgenzie(Set<GaraAgenzia> garaAgenzie) {
        this.garaAgenzie.clear();
        this.garaAgenzie = garaAgenzie;
    }

    public Set<GaraServizio> getGaraServizi() {
        return garaServizi;
    }

    public void setGaraServizi(Set<GaraServizio> garaServizi) {
        this.garaServizi.clear();
        this.garaServizi = garaServizi;
    }

        public void GaraServizio(GaraServizio gara_servizio) {
            garaServizi.add(gara_servizio);
            gara_servizio.setGara(this);
        }

        public void removeGaraServizio(GaraServizio gara_servizio) {
            garaServizi.remove(gara_servizio);
            gara_servizio.setGara(null);
        }

        public void GaraAgenzia(GaraAgenzia gara_agenzia) {
            garaAgenzie.add(gara_agenzia);
            gara_agenzia.setGara(this);
        }

        public void removeGaraAgenzia(GaraAgenzia gara_agenzia) {
            garaAgenzie.remove(gara_agenzia);
            gara_agenzia.setGara(null);
        }







    public String getTitolo() {
        return titolo;
    }

    public void setTitolo(String titolo) {
        this.titolo = titolo;
    }

    public int getObiettivo() {
        return obiettivo;
    }

    public void setObiettivo(int obiettivo) {
        this.obiettivo = obiettivo;
    }

    public float getBonus() {
        return bonus;
    }

    public void setBonus(float bonus) {
        this.bonus = bonus;
    }

    public Date getDataIniziale() {
        return dataIniziale;
    }

    public void setDataIniziale(Date dataIniziale) {
        this.dataIniziale = dataIniziale;
    }

    public Date getDataFinale() {
        return dataFinale;
    }

    public void setDataFinale(Date dataFinale) {
        this.dataFinale = dataFinale;
    }

    @Override
    public String toString() {
        return "Gara [garaAgenzie=" + garaAgenzie + ", garaServizi="
                + garaServizi + ", titolo=" + titolo + ", obiettivo="
                + obiettivo + ", bonus=" + bonus + ", dataIniziale="
                + dataIniziale + ", dataFinale=" + dataFinale + "]";
    }

    @Override
    public int hashCode() {
        final int prime = 31;
        int result = super.hashCode();
        result = prime * result + Float.floatToIntBits(bonus);
        result = prime * result
                + ((dataFinale == null) ? 0 : dataFinale.hashCode());
        result = prime * result
                + ((dataIniziale == null) ? 0 : dataIniziale.hashCode());
        result = prime * result + obiettivo;
        result = prime * result + ((titolo == null) ? 0 : titolo.hashCode());
        return result;
    }

    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        Gara other = (Gara) obj;
        if (Float.floatToIntBits(bonus) != Float.floatToIntBits(other.bonus))
            return false;
        if (dataFinale == null) {
            if (other.dataFinale != null)
                return false;
        } else if (!dataFinale.equals(other.dataFinale))
            return false;
        if (dataIniziale == null) {
            if (other.dataIniziale != null)
                return false;
        } else if (!dataIniziale.equals(other.dataIniziale))
            return false;
        if (obiettivo != other.obiettivo)
            return false;
        if (titolo == null) {
            if (other.titolo != null)
                return false;
        } else if (!titolo.equals(other.titolo))
            return false;
        return true;
    }


}


GaraAgenzia.java:

@Entity
@Table(name = "gare_agenzie")
@AssociationOverrides({
        @AssociationOverride(name = "pk.gara",
            joinColumns = @JoinColumn(name = "gara_id")),
        @AssociationOverride(name = "pk.agenzia",
            joinColumns = @JoinColumn(name = "agenzia_id")) })

public class GaraAgenzia implements Serializable {

    private static final long serialVersionUID = 3865586469933888797L;


    /*
     * inizializzo logger
     */
    static Logger logger = LoggerFactory.getLogger(GaraAgenzia.class);

    /*
     *
     * numero contratti:
     *
     *
     */
    private int numeroContratti = 0;

    private GaraAgenziaId pk = new GaraAgenziaId();

    @EmbeddedId
    public GaraAgenziaId getPk() {
          return pk;
    }

    public void setPk(GaraAgenziaId pk) {
          this.pk = pk;
    }

    @Transient
    public Gara getGara() {
        return getPk().getGara();
    }

    public void setGara(Gara gara) {
        getPk().setGara(gara);
    }

    @Transient
    public Agenzia getAgenzia() {
        return getPk().getAgenzia();
    }

    public void setAgenzia(Agenzia agenzia) {
        getPk().setAgenzia(agenzia);
    }


    @Column(name = "numero_contratti")
    public int getNumeroContratti() {
        return numeroContratti;
    }

    public void setNumeroContratti(int numeroContratti) {
        this.numeroContratti = numeroContratti;
    }

      public boolean equals(Object other) {
            if (this == other) return true;
            if ( !(other instanceof GaraAgenzia) ) return false;

            final GaraAgenzia gara_agenzia = (GaraAgenzia) other;

            if ( !gara_agenzia.getGara().equals( getGara() ) ) return false;
            if ( !gara_agenzia.getAgenzia().equals( getAgenzia() ) ) return false;

            return true;
        }

        public int hashCode() {
            int result;
            result = getGara().hashCode();
            result = 29 * result + getAgenzia().hashCode();
            return result;
        }
}


GaraAgenziaId.java:

@Embeddable
public class GaraAgenziaId implements Serializable {

    private static final long serialVersionUID = 4934033367128755763L;


    /*
     * inizializzo logger
     */
    static Logger logger = LoggerFactory.getLogger(GaraAgenziaId.class);

    private Gara gara;

    private Agenzia agenzia;

    @ManyToOne
    public Gara getGara() {
        return gara;
    }

    public void setGara(Gara gara) {
        this.gara = gara;
    }

    @ManyToOne
    public Agenzia getAgenzia() {
        return agenzia;
    }

    public void setAgenzia(Agenzia agenzia) {
        this.agenzia = agenzia;
    }

    /*
     * override del metodo di uguaglianza
     */
    @Override
    public boolean equals(Object o) {
        if (this == o)
            return true;
        if (o == null)
            return false;

        if (o instanceof GaraAgenzia) {
            final GaraAgenzia other = (GaraAgenzia) o;
            return (Objects.equal(getGara().getId(), other.getGara().getId())) && (Objects.equal(getAgenzia().getId(), other.getAgenzia().getId()));
        }
        return false;
    }

    /*
     * override del metodo creazione hashcode
     */
    @Override
    public int hashCode() {
        return Objects.hashCode(getGara().getId(), getAgenzia().getId());
    }


    /*
      public boolean equals(Object other) {
            if (this == other) return true;
            if ( !(other instanceof GaraAgenziaId) ) return false;

            final GaraAgenziaId gara_agenzia = (GaraAgenziaId) other;

            if ( !gara_agenzia.getGara().equals( getGara() ) ) return false;
            if ( !gara_agenzia.getAgenzia().equals( getAgenzia() ) ) return false;

            return true;
        }

        public int hashCode() {
            int result;
            result = getGara().hashCode();
            result = 29 * result + getAgenzia().hashCode();
            return result;
        }

    */

    /*
    @Override
    public boolean equals(Object obj) {
        if (this == obj)
            return true;
        if (!super.equals(obj))
            return false;
        if (getClass() != obj.getClass())
            return false;
        GaraAgenziaId other = (GaraAgenziaId) obj;
        if (gara == null) {
            if (other.gara != null)
                return false;
        } else if (!gara.equals(other.gara))
            return false;
        if (agenzia == null) {
            if (other.agenzia != null)
                return false;
        } else if (!agenzia.equals(other.agenzia))
            return false;
        return true;
    }
    */
}


编辑1:
如果我之前清除代理机构(和服务)的集合
再次设置:

    garaToUpdate.getGaraAgenzie().clear();
    garaToUpdate.getGaraServizi().clear();

    getCurrentSession().flush();

    garaToUpdate.setGaraAgenzie(gara.getGaraAgenzie());
    garaToUpdate.setGaraServizi(gara.getGaraServizi());

    getCurrentSession().update(garaToUpdate);


我收到此错误:


  不再包含带有cascade =“ all-delete-orphan”的集合
  拥有实体实例引用的对象:


编辑2:
如@JamesB所建议,我将toString方法添加到GaraAgenzia和GaraAgenziaId。这里的结果是在更新Gara记录之前:

这是在更新之前从数据库获取的记录


  信息:com.machinet.model.GaraAgenziaId-garaToUpdate.GaraAgenzie
  (更新前):[GaraAgenzia [numeroContratti = 0,pk = GaraAgenziaId
  [Gara = Gara [titolo = gara title,obiettivo = 999,bonus = 100.00,
  dataIniziale = 2014-07-31,dataFinale = 2014-07-31],agenzia = Agenzia(id = 1,
  nome ='Agency 1 ltd',ragione sociale = Agency 1 ltd srl)]]]


这是将在db中设置的编辑记录:


  INFO:com.machinet.model.GaraAgenziaId-editedGara.GaraAgenzie
  (更新前):[GaraAgenzia [numeroContratti = 0,pk = GaraAgenziaId
  [Gara = Gara [titolo = gara title,obiettivo = 999,bonus = 100.00,
  dataIniziale = 2014-07-31,dataFinale = 2014-07-31],agenzia = Agenzia(id = 1,
  nome ='Agency 1 ltd',ragione sociale = Agency 1 ltd srl]]]

最佳答案

这些似乎运作良好。我张贴希望有人会发现它有用:

GaraAgenzia类:

public boolean equals(Object o) {
        if (this== o) return true;
        if (o ==null|| getClass() != o.getClass()) return false;

        GaraAgenzia that = (GaraAgenzia) o;

        if (getPk() !=null?!getPk().equals(that.getPk()) : that.getPk() !=null) return false;

        return true;
    }

    public int hashCode() {
        return (getPk() !=null? getPk().hashCode() : 0);
    }


GaraAgenziaId类别:

public boolean equals(Object o) {
    if (this== o) return true;
    if (o ==null|| getClass() != o.getClass()) return false;

    GaraAgenziaId that = (GaraAgenziaId) o;

    if (gara !=null?!gara.equals(that.gara) : that.gara !=null) return false;
    if (agenzia !=null?!agenzia.equals(that.agenzia) : that.agenzia !=null)
        return false;

    return true;
}

public int hashCode() {
    int result;
    result = (agenzia !=null? agenzia.hashCode() : 0);
    result =31* result + (gara !=null? gara.hashCode() : 0);
    return result;
}

07-24 22:19