使用彼此的引用复制嵌套对象

时间:2017-12-21 11:39:45

标签: java oracle

我在数据库中有两个表有一对多的关系。 当我获取表User时,我想将User中的数据(与Vehicle相关的数据)复制到另一个对象UserDuplicate(和VehicleDuplicate)。 我尝试使用BeanUtils.copyProperties,但嵌套引用仍然引用旧对象。 我想知道复制嵌套对象的方法是什么。 谢谢。

import java.util.Set;


public class User {

    private Set<Vehicle> vehs = new HasHSet();

    public Set<Vehicle> getVehs() {
        return vehs;
    }

    public void setVehs(Set<Vehicle> vehs) {
        this.vehs = vehs;
    }
}

class Vehicle {

    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;

    }
}

class UserDuplicate {

    private Set<VehicleDuplicate> vehDup=new HasHSet();

    public Set<VehicleDuplicate> getVehDup() {
        return vehDup;
    }

    public void setVehDup(Set<VehicleDuplicate> vehDup) {
        this.vehDup = vehDup;
    }   
}

class VehicleDuplicate {

    private UserDuplicate userDup;

    public UserDuplicate getUserDup() {
        return userDup;
    }

    public void setUserDup(UserDuplicate userDup) {
        this.userDup = userDup;
    }   
}

2 个答案:

答案 0 :(得分:0)

我喜欢在这些情况下使用复制构造函数:

class UserDuplicate {

...

UserDuplicate(User user) {

...

    if (user.getVehs() != null) {
        vehDup = new HashSet<>();
        for (Vehicle v: user.getVehs()) {
            vehDup.add(new VehicleDuplicate(this, v));
        }
    }
}

...

class VehicleDuplicate {

...

VehicleDuplicate(UserDuplicate userDup, Vehicle veh) {
    this.userDup = userDup;

...

}

答案 1 :(得分:0)

一种方法可能是使用映射器将所需内容复制到重复对象,这种方法可以减轻代码的占用空间......

例如,您可以使用jackson-databind

ObjectMapper mapper = new ObjectMapper();
mapper.configure(SerializationFeature.FAIL_ON_EMPTY_BEANS, false);
UserDuplicate duplicated = mapper.readValue(mapper.writeValueAsString(source), UserDuplicate.class);
// set the correct duplicate user in the duplicated vehicule
duplicated.getVehDup().forEach(x -> x.setUserDup(duplicated));

这会将source对象序列化为JSON,然后将其反序列化为duplicated对象的实例。

因为你说你的模式或多或少相同,你可以照顾杰克逊提供的注释,例如忽略某些领域。

static class User {

    @JsonIgnore // Allows to ignore attributes from stadging to production
    private String iDontWantToCopyThis = "blablabla";

    private Set<Vehicle> vehs;

    public Set<Vehicle> getVehs() {
        return vehs;
    }

    public void setVehs(Set<Vehicle> vehs) {
        this.vehs = vehs;
    }
}

执行此操作时,iDontWantToCopyThis字段不会被复制到重复的对象中。

由于您的Vehicle包含对user的引用,因此您需要使用@JsonIgnore进行注释,以避免在反序列化期间出现递归。

static class Vehicle {

    @JsonIgnore 
    private User user;

    public User getUser() {
        return user;
    }

    public void setUser(User user) {
        this.user = user;

    }
}

因为vehicule集的名称与UserDuplicate类不同,所以必须使用注释@JsonProperty("vehs")让映射器知道如何匹配数据。

 static class UserDuplicate {

    @JsonProperty("vehs") // need to specify the source name into the json used to load the user duplicated
    private Set<VehicleDuplicate> vehDup;

    public Set<VehicleDuplicate> getVehDup() {
        return vehDup;
    }

    public void setVehDup(Set<VehicleDuplicate> vehDup) {
        this.vehDup = vehDup;
    }   
}

如果您的数据转换过于复杂,无法通过注释进行处理,您还可以创建自定义序列化程序或反序列化程序......