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