Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/374.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 序列化后在ArrayList上调用equals_Java_Serialization_Jpa_Arraylist_Rmi - Fatal编程技术网

Java 序列化后在ArrayList上调用equals

Java 序列化后在ArrayList上调用equals,java,serialization,jpa,arraylist,rmi,Java,Serialization,Jpa,Arraylist,Rmi,我遇到了一个奇怪的问题,关于通过RMI传输的对象上的等式。 这几天来一直困扰着我,我想知道是否有人能帮我解释一下这个问题 我有一个Garage类(如果相关的话,它也是一个JPA实体),我将它推送到一个名为X over RMI的java进程(因此这个对象正在被序列化)。车库对象存储一个名为Car的对象列表(也称为JPA实体),这些对象也是可序列化的 Garage上的equals方法基本上是在其汽车列表(ArrayList)上调用equals 当我在java进程中调用equals时,它不会出于某种原

我遇到了一个奇怪的问题,关于通过RMI传输的对象上的等式。 这几天来一直困扰着我,我想知道是否有人能帮我解释一下这个问题

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

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

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

奇怪的是,当单元测试时,它确实对Cars数组列表的所有成员调用了equals。作为单元测试的一部分,我甚至序列化了这些对象,这也起到了作用。有什么想法吗?我希望我能把问题说清楚,请随时询问任何信息以澄清任何问题

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

@实体
@表(schema=“pdw”,name=“garage”)
公共级车库
实现可比性,
可序列化{
私有静态最终长serialVersionUID=1L;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私有字符串id;
私有字符串名称;
@OneToMany(级联=级联类型.ALL)
@JoinTable(schema=“pdw”)
私家车列表=新的ArrayList();
公共字符串getId(){
返回id;
}
公共无效集合id(字符串id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共列表getCars(){
返回车辆;
}
公共车辆(列出车辆){
这个。汽车=汽车;
}
@凌驾
公共字符串toString(){
StringBuffer=新的StringBuffer();
缓冲区。追加(“[”);
buffer.append(“Garage:”);
buffer.append(“[id:+id+]”);
缓冲区。追加(“[Cars:+Cars+]”);
缓冲区。追加(“]”);
返回buffer.toString();
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(!(车库的obj实例))
返回false;
车库其他=(车库)obj;
if(name==null){
if(other.name!=null)
返回false;
}如果(!name.equals(other.name))
返回false;
if(cars==null){
if(other.cars!=null)
返回false;
}如果(!cars.equals(other.cars))
返回false;
返回true;
}
@凌驾
公共内部比较(车库其他){
返回这个.getName().compareTo(other.getName());
}
}
@实体
@表(schema=“pdw”,name=“car”)
公车
实现可序列化{
私有静态最终长serialVersionUID=1L;
@身份证
@GeneratedValue(策略=GenerationType.AUTO)
私有字符串id;
私有字符串名称;
@OneToOne(fetch=FetchType.LAZY)
私人车库;
公共字符串getId(){
返回id;
}
公共无效集合id(字符串id){
this.id=id;
}
公共字符串getName(){
返回名称;
}
公共void集合名(字符串名){
this.name=名称;
}
公共车库{
返回车库;
}
公共车库(车库){
这个车库=车库;
}
@凌驾
公共布尔等于(对象obj){
if(this==obj)
返回true;
if(obj==null)
返回false;
如果(getClass()!=obj.getClass())
返回false;
汽车其他=(汽车)obj;
if(name==null){
if(other.name!=null)
返回false;
}如果(!name.equals(other.name))
返回false;
返回true;
}
@凌驾
公共字符串toString(){
StringBuffer=新的StringBuffer();
缓冲区。追加(“[”);
buffer.append(“Car:”);
buffer.append(“[id:+id+]”);
buffer.append(“[name:+name+]”);
append(“[garage:+garage.getName()+”]);
缓冲区。追加(“]”);
返回buffer.toString();
}   
}
  • 请确保您的
    列表在反序列化后不为空
  • equals
    方法中放置一个断点,看看是否没有发生任何错误
  • 确保在
    Car
    上执行的
    equals
    是正确的
  • 检查是否没有
    瞬态
    字段

  • 检查您期望成为
    数组列表的内容是否实际上不是
    持久性包
    。因为它的
    等于
    不会做你想做的事。如果它是
    PersistentBag
    ,则可以在通过线路发送之前将其传输到
    ArrayList
    (从而防止潜在的
    LazyInitializationException
    ),或者对每个元素而不是
    列表本身调用equals。Hibernate使用
    PersistentBag
    包装您的集合,以提供延迟加载

另外,如果您使用的是JPA提供程序而不是Hibernate,那么它可能有类似的集合包装器。指出您的持久性提供者。

要展开Bozho:

  • 检查两侧的类是否具有相同的
    serialVersionUID
    (即具有完全相同的编译版本)。我
    @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();
        }   
    }
    
    public boolean equals(Object o) {
    if (o == this)
        return true;
    if (!(o instanceof List))
        return false;
    
    ListIterator<E> e1 = listIterator();
    ListIterator e2 = ((List) o).listIterator();
    while(e1.hasNext() && e2.hasNext()) {
        E o1 = e1.next();
        Object o2 = e2.next();
        if (!(o1==null ? o2==null : o1.equals(o2)))
        return false;
    }
    return !(e1.hasNext() || e2.hasNext());
    }
    
        if (obj == null)
                return false;
        if (getClass() != obj.getClass())
                return false;
    
    if (!(obj instanceof Car)){
                return false;
    }
    
    /**
     * Bag does not respect the collection API and do an
     * JVM instance comparison to do the equals.
     * The semantic is broken not to have to initialize a
     * collection for a simple equals() operation.
     * @see java.lang.Object#equals(java.lang.Object)
     */
    public boolean equals(Object obj) {
        return super.equals(obj);
    }
    
    public static boolean areEqualNonNullLists(List thisList, List thatList)
    {
        if(thisList.size() != thatList.size()) return false;
    
        for(int i=0; i<thisList.size(); i++)
        {
            if(!thisList.get(i).equals( thatList.get(i) ) ) return false;
        }
        return true;
    }