【发布时间】:2011-09-27 07:03:14
【问题描述】:
我的应用程序中出现了一个奇怪的问题,我将快速解释全局架构,然后深入解释我的问题。
我使用服务填充来自我的数据库(JPA 驱动)的HashMap<DomainObject,Boolean>,然后通过 EJB 远程方法调用(使用 Apache Wicket)返回到我的视图。在这一部分中,我将一个新的DomainObject 添加到返回的映射中,以便存储来自我的最终用户的任何新值。
当用户在其浏览器中点击“添加”按钮时会出现问题,我尝试在我的地图中检索新创建的项目,但它失败了。通过使用调试器,我面临以下问题。
假设HashMap<DomainObject, Boolean> map 和DomainObject do 是两个有趣的变量,我在调试器中有以下结果
map.keySet(); 给了我一个对应于do 的对象(即使@whatever simili-reference 相同),两个对象上的hashcode() 返回相似的值,两个对象之间的equals() 返回true
map.containsKey(do); 返回false
map.get(do);返回null,很奇怪,因为我的密钥似乎在map。
假设我新创建的项目是keySet() 枚举的第一个键,我执行以下操作:
map.get(new ArrayList(map.keySet()).get(0)),它返回null。
如果有帮助,通过在我的 DomainObject.equals() 和 DomainObject.hashcode() 方法上附加断点,我发现 map.get() 只调用 hashcode() 而不是 equals()。
我发现的唯一解决方法是在现有的 new HashMap(map) 之上重新创建一个新地图,在这个新地图中,我完全没有问题通过它的键查找对象。
希望这里的人能指点一下会发生什么,谢谢。
使用环境:
- OS X 10.7.1 下的 Sun Java 1.6.0_26 x64
- Debian 6.0.2 (2.6.32) 下的 OpenJDK 1.6.0_18 x64
- Apache Wicket 1.4.17
- Oracle Glassfish 3.1.1
- JBoss 休眠 3.6.5
DomainObject代码:
public class AssetComponentDetailTemplate extends BaseEntite<Long> {
public enum DataType {
TXT,
DATE,
INT,
JOIN,
LIST,
COULEURS,
REFERENCE
}
public enum Tab {
IDENTITE,
LOCALISATION,
CYCLE_DE_VIE,
FINANCE,
RESEAU,
DETAIL
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@Column(nullable = false)
private String name;
@Column(nullable = false)
@Enumerated(EnumType.STRING)
private DataType dataType;
private Integer classNameId;
private Long orderId;
private Long nextAssetComponentDetailTemplateId;
private String unit;
@Enumerated(EnumType.STRING)
private Tab tab;
@Column(nullable = false)
private Long uniqueOrganizationId;
@OneToMany(fetch = FetchType.LAZY)
@JoinColumn(name = "idAssetComponentDetailTemplate", insertable = false, updatable = false)
private List<AssetComponentDetailJoin> assetComponentDetailJoins;
private Boolean mandatory = false;
public AssetComponentDetailTemplate() {
}
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(final String name) {
this.name = name;
}
public DataType getDataType() {
return dataType;
}
public void setDataType(final DataType dataType) {
this.dataType = dataType;
}
public Integer getClassNameId() {
return classNameId;
}
public void setClassNameId(final Integer classNameId) {
this.classNameId = classNameId;
}
public Long getUniqueOrganizationId() {
return uniqueOrganizationId;
}
public void setUniqueOrganizationId(final Long uniqueOrganizationId) {
this.uniqueOrganizationId = uniqueOrganizationId;
}
public Long getNextAssetComponentDetailTemplateId() {
return nextAssetComponentDetailTemplateId;
}
public void setNextAssetComponentDetailTemplateId(final Long nextAssetComponentDetailTemplateId) {
this.nextAssetComponentDetailTemplateId = nextAssetComponentDetailTemplateId;
}
public String getUnit() {
return unit;
}
public void setUnit(final String unit) {
this.unit = unit;
}
public Tab getTab() {
return tab;
}
public void setTab(final Tab tab) {
this.tab = tab;
}
public Long getOrder() {
return orderId;
}
public void setOrder(final Long order) {
this.orderId = order;
}
public Boolean isMandatory() {
return mandatory;
}
@Override
public String toString() {
return name;
}
@Override
public boolean equals(final Object o) {
if (this == o) {
return true;
}
if (o == null || getClass() != o.getClass()) {
return false;
}
final AssetComponentDetailTemplate that = (AssetComponentDetailTemplate) o;
if (classNameId != null ? !classNameId.equals(that.classNameId) : that.classNameId != null) {
return false;
}
if (dataType != that.dataType) {
return false;
}
if (id != null ? !id.equals(that.id) : that.id != null) {
return false;
}
if (name != null ? !name.equals(that.name) : that.name != null) {
return false;
}
if (nextAssetComponentDetailTemplateId != null ?
!nextAssetComponentDetailTemplateId.equals(that.nextAssetComponentDetailTemplateId) :
that.nextAssetComponentDetailTemplateId != null) {
return false;
}
if (orderId != null ? !orderId.equals(that.orderId) : that.orderId != null) {
return false;
}
if (tab != that.tab) {
return false;
}
if (uniqueOrganizationId != null ? !uniqueOrganizationId.equals(that.uniqueOrganizationId) :
that.uniqueOrganizationId != null) {
return false;
}
if (unit != null ? !unit.equals(that.unit) : that.unit != null) {
return false;
}
return true;
}
@Override
public int hashCode() {
int result = id != null ? id.hashCode() : 0;
result = 31 * result + (name != null ? name.hashCode() : 0);
result = 31 * result + (dataType != null ? dataType.hashCode() : 0);
result = 31 * result + (classNameId != null ? classNameId.hashCode() : 0);
result = 31 * result + (orderId != null ? orderId.hashCode() : 0);
result = 31 * result +
(nextAssetComponentDetailTemplateId != null ? nextAssetComponentDetailTemplateId.hashCode() : 0);
result = 31 * result + (unit != null ? unit.hashCode() : 0);
result = 31 * result + (tab != null ? tab.hashCode() : 0);
result = 31 * result + (uniqueOrganizationId != null ? uniqueOrganizationId.hashCode() : 0);
return result;
}
【问题讨论】:
-
你应该显示一些代码。至少你如何管理地图以及
equals和hashCode的实现。 -
我们可以看看一些代码吗?
-
恐怕提取代码不会很容易(它在应用程序中是紧密耦合的)。我添加
DomainObject代码。