当我使用@idclass linkedhashset时包括重复项目
-
11-12-2019 - |
题
我有任务准备引用搜索屏幕。我提到了Oracle View 创建报价模型。由于视图表中没有ID列,我更喜欢使用@idClass注释通过QuoteId.class使用复合ID。我在两个模型上覆盖了哈希码并等于方法。 Quoteid等于和HashCode返回所有字段的组合,引用哈希码和等式只需在模型中比较它的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就具有所有项目,即使是他们的报价编号也是一样的。我缺少任何其他实施,以通过报价无字段(可比较,比较器)验证每个项目唯一性吗?如果我跟踪uniquoteResult列表中,则它们中的所有值都有相同的报价编号。
编辑注意事项:我已更改了我使用Apache Library HashCodeBuilder和EqualsBuilder支持的方式,但问题保持不变。我害怕idclass哈希码对于linkedhashset为生效
解决方案
在您的模型中使用以下代码,您测试就是这样.quoteno与obj.quoteno相同的实例:
@Override
public boolean equals(Object obj)
{
// TODO Auto-generated method stub
return this.quoteNo == ((EprocAwquoteV) obj).quoteNo;
}
.
结果是,具有单独构造的idclass实例的两个实例将被认为是不是等于,如果quoteno不相同的对象。我猜你想测试quoteno的平等,而不是这样的东西:
this.quoteNo.equals(other.quoteNo);
.
还存在型号的当前实现的其他一些问题(例如它可以投掷ClassCastException)。可以找到基本原则: Object.equals 和覆盖java equals()方法quirk 。 另外,休眠,重要的是要记住,你不应该测试是相同的,但使用instanceof(因为代理类)。有关写作等于和实体的哈希码的一些说明可以从 hibernate文档。
编辑:
您目前的方法不起作用,因为
.
return new EqualsBuilder().appendSuper(super.equals(other))
将其煮沸到物体。如果您没有超级类,则具有有意义的等于实施。我并不完全肯定我理解你的案子是否正确,所以也许你可以查看以下工作示例,并找出差异的位置:
.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));