由OpenSessionInView引出的List复制问题

public String toAuditUser(ModelMap map){

List<UserInfo> users = authService.getAuditUsers();
List<UserInfo> tmpUsers = new ArrayList<UserInfo>(users);
for(UserInfo user : tmpUsers){
String provinceCode = user.getProvince();
String cityCode = user.getCity();
user.setProvince(PcUtils.getProvince(provinceCode));
user.setCity(PcUtils.getCity(cityCode));
}
map.put(“users”, tmpUsers);
return “/sa/auditUser”;

}

上面的方法从数据库中取出users列表,for循环中是用PcUtils这个工具类将用户的省市代码转换为省市名称。运行中发现给用户的省市重新赋值后数据库中的值也随之改变,这肯定是由于Hibernate的Session机制导致的,一个直接的方法是关闭OpenSessionInView Interceptor。

另一种方法是将session中的users取出来,复制到另一个List中,但是发现原来通过以下两种方法都仍然只是拷贝引用,引用指向的对象仍是同一块内存!

1.List<UserInfo> tmpUsers = new ArrayList<UserInfo>(users);

2. List<UserInfo> tmpUsers = new ArrayList<UserInfo>();

tmpUsers.addAll(users);

网上寻找解决方案:http://blog.csdn.net/liulin_good/article/details/6109090,发现以下两种方法还是不行:

3. List<UserInfo> tmpUsers = new ArrayList<UserInfo>(Arrays.asList(new UserInfo[users.size()]));
Collections.copy(tmpUsers, users);

4.  List<UserInfo> tmpUsers = new CopyOnWriteArrayList<UserInfo>(users);

最后,在StackOverFlow上看到这样一段话:

The answer by Stephen Katulka (accepted answer) is wrong (the second part). It explains that Collections.copy(b, a); does a deep copy, which it does not. Both, new ArrayList(a); and Collections.copy(b, a); only do a shallow copy. The difference is, that the constructor allocates new memory, and copy(...) does not, which makes it suitable in cases where you can reuse arrays, as it has a performance advantage there.

The Java standard API tries to discourage the use of deep copies, as it would be bad if new coders would use this on a regular basis, which may also be one of the reason why clone() is not public by default.

The source code for Collections.copy(...) can be seen on line 552 at: http://www.java2s.com/Open-Source/Java-Document/6.0-JDK-Core/Collections-Jar-Zip-Logging-regex/java/util/Collections.java.htm

If you need a deep copy, you have to iterate over the items manually, using a for loop and clone() on each object.


http://www.sachiel.net/?p=49

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值