gpt4 book ai didi

java - 序列化后在 ArrayList 上调用 equals

转载 作者:行者123 更新时间:2023-12-01 06:41:53 25 4
gpt4 key购买 nike

我遇到了一个与通过 RMI 传输的对象上的 equals 相关的奇怪问题。这几天来这一直困扰着我,我想知道是否有人可以帮助阐明这个问题。

我有一个 Garage 类(如果相关,它也是一个 JPA 实体),我通过 RMI 将其推送到名为 X 的 java 进程(因此该对象正在被序列化)。 Garage 对象存储称为 Car(也是 JPA 实体)的对象列表,这些对象也是可序列化的。

Garage 上的 equals 方法基本上是在其汽车列表(ArrayList)上调用 equals

当我在java进程中调用equals时,由于某种原因,它不会像我期望的那样在列表上调用equals,我希望它在列表中的所有汽车上调用equals来检查列表是否相等,但它不会这样做这个。

奇怪的是,当单元测试时,它确实对 Cars ArrayList 的所有成员调用 equals。我什至将对象序列化作为单元测试的一部分,这也有效。有任何想法吗?我希望我能解决这个问题,请随时请求任何信息来澄清任何事情。

编辑:我几乎可以肯定它的 ArrayList 很奇怪,因为当我在对象中手动执行 equals 而不是在汽车列表上调用 equals 时,我在汽车列表上执行了 foreach 循环并调用equals 在每辆车上(就像我期望的 ArrayList equals 无论如何,它按预期工作)

@Entity
@Table(schema="pdw", name="garage")
public class Garage
implements Comparable<Garage> ,
Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;

private String name;


@OneToMany(cascade = CascadeType.ALL)
@JoinTable(schema="pdw")
private List<Car> cars = new ArrayList<Car>();

public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public List<Car> getCars() {
return cars;
}
public void setCars(List<Car> cars) {
this.cars = cars;
}

@Override
public String toString() {

StringBuffer buffer = new StringBuffer();
buffer.append("[");
buffer.append("Garage:");
buffer.append("[id:" + id + "]");
buffer.append("[Cars:" + cars + "]");
buffer.append("]");
return buffer.toString();
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof Garage))
return false;
Garage other = (Garage) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
if (cars == null) {
if (other.cars != null)
return false;
} else if (!cars.equals(other.cars))
return false;
return true;
}

@Override
public int compareTo(Garage other) {
return this.getName().compareTo(other.getName());
}
}

@Entity
@Table(schema="pdw", name="car")
public class Car
implements Serializable {

private static final long serialVersionUID = 1L;

@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private String id;

private String name;

@OneToOne(fetch = FetchType.LAZY)
private Garage garage;

public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Garage getGarage() {
return garage;
}
public void setGarage(Garage garage) {
this.garage = garage;
}

@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Car other = (Car) obj;
if (name == null) {
if (other.name != null)
return false;
} else if (!name.equals(other.name))
return false;
return true;
}

@Override
public String toString() {

StringBuffer buffer = new StringBuffer();
buffer.append("[");
buffer.append("Car:");
buffer.append("[id:" + id + "]");
buffer.append("[name:" + name + "]");
buffer.append("[garage:" + garage.getName() + "]");
buffer.append("]");
return buffer.toString();
}
}

最佳答案

  • 确保反序列化后您的列表不为空。
  • equals 方法中放置一个断点,看看是否没有发生任何错误
  • 确保您在 Car 上的 equals 实现正确
  • 检查是否没有transient字段

  • 检查您期望的 ArrayList 是否实际上不是 PersistentBag。因为它的 equals 不会做你想要的。如果它是 PersistentBag,您可以在通过网络发送之前将其传输到 ArrayList(从而防止潜在的 LazyInitializationException),或者调用 equals在每个元素上而不是在 List 本身上。 Hibernate 使用 PersistentBag 来包装您的集合以提供延迟加载

附注如果您使用 Hibernate 之外的 JPA 提供程序,也许它有类似的集合包装器。指出您的持久性提供者是什么。

关于java - 序列化后在 ArrayList 上调用 equals,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/1866456/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com