我的任务是准备报价搜索屏幕。我已经提到了Oracle视图 创建报价模型。由于视图表中没有id列,我更喜欢通过quoteId.class使用@IdClass注释来使用复合id。我在两个模型上覆盖hashCode和equals方法。 quoteId等于& hashcode返回所有字段的组合并引用hashcode& equals只是比较模型中的this.quoteNo字段。
引用模型:
@Override
public int hashCode()
{
return new HashCodeBuilder(17,37)
.append(quoteNo)
.toHashCode();
}
/*
* (non-Javadoc)
*
* @see java.lang.Object#equals(java.lang.Object)
*/
@Override
public boolean equals(Object obj)
{
final quoteModel other = (quoteModel ) obj;
return new EqualsBuilder().appendSuper(super.equals(other))
.append(quoteNo, other.quoteNo).isEquals();
}
当我需要独特的物品时,我只是通过以下方式访问:
uniqueQuoteResults = new ArrayList<Quote>(
new LinkedHashSet<Quote>(fullQuoteResults));
但是当我开始使用idClass时,我的linkedHashSet甚至包含所有项目的报价编号相同。我是否缺少任何其他实现来证明每个项目的唯一性通过引用no字段(比较,比较)?如果我跟踪uniqueQuoteResult列表项值,则所有值都具有相同的引号。
编辑注意:我已经改变了使用apache库HashCodeBuilder和EqualsBuilder支持的方法,但问题保持不变。我担心idClass哈希码对于linkedhashset
有效答案 0 :(得分:2)
使用模型中的以下代码进行测试就是this.quoteNo与obj.quoteNo相同的实例:
@Override
public boolean equals(Object obj)
{
// TODO Auto-generated method stub
return this.quoteNo == ((EprocAwquoteV) obj).quoteNo;
}
结果是,如果quoteNo不是同一个对象,那么具有单独构造的IdClass实例的两个实例将被视为不等于。我想你想测试quoteNo&#39; s的相等性,而不是像:
this.quoteNo.equals(other.quoteNo);
当前在模型中实现equals时还存在一些其他问题(例如,它可能抛出ClassCastException)。基本原则可以从以下网址找到:Object.equals和Overriding the java equals() method quirk。 另外,对于Hibernate,重要的是要记住,您不应该测试类是否相同,而是使用instanceof(因为代理类)。关于为实体编写equals&amp; hascode的一些说明可以从Hibernate documentation找到。
修改强> 您当前的方法不起作用,因为
return new EqualsBuilder().appendSuper(super.equals(other))
将其归结为Object.equals。如果你没有有意义的equals实现的超类。我不完全确定我理解你的情况,所以也许你可以看看下面的工作例子,找出差异的地方:
public class QuoteId implements Serializable {
private int id1;
private int id2;
public QuoteId() {}
//This equals does not matter when we build LinkedHashSet
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
QuoteId other = (QuoteId) o;
return id1 == other.id1 && id2 == other.id2;
}
public int hashCode() {
return 31 * id1 + id2;
}
}
@Entity
@IdClass(QuoteId.class)
public class Quote {
@Id private int id1;
@Id private int id2;
String value;
public Quote() {
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
Quote other = (Quote) o;
return id1 == other.id1 && id2 == other.id2;
}
@Override
public int hashCode() { return 31 * id1 + id2;}
//get&set for id1, id2, and value are omitted
}
tx.begin();
em.persist(new Quote(1, 1, "val"));
em.persist(new Quote(1, 2, "val"));
tx.commit();
TypedQuery<Quote> query = em.createQuery("SELECT q FROM Quote q", Quote.class);
List<Quote> twoQuotes = query.getResultList();//both
//duplicating (size=4) result for sake of test;
List<Quote> fullQuoteResults = new ArrayList<Quote>();
fullQuoteResults.addAll(twoQuotes);
fullQuoteResults.addAll(twoQuotes);
//will have same elements as in twoQuotes:
List<Quote> uniqueQuoteResults = new ArrayList<Quote>(
new LinkedHashSet<Quote>(fullQuoteResults));