2013-07-09 2 views
-1
public class CustomerDTO { 
    private int customerId; 
    private String customerName; 
    private String customerAddress; 

    public int getCustomerId() { 
     return customerId; 
    } 
    public void setCustomerId(int customerId) { 
     this.customerId = customerId; 
    } 
    public String getCustomerName() { 
     return customerName; 
    } 
    public void setCustomerName(String customerName) { 
     this.customerName = customerName; 
    } 
    public String getCustomerAddress() { 
     return customerAddress; 
    } 
    public void setCustomerAddress(String customerAddress) { 
     this.customerAddress = customerAddress; 
    } 
} 

класс CustomerDAO:Добавление объектов (копируется через оборонительный копирования с использованием BeanUtils) в ArrayList давая затхлый данные: Spring 3

import java.util.ArrayList; 
import java.util.List; 
import java.util.Collections; 

public final class CustomerDAO { 
    private CustomerDTO customer; 

    public void setCustomer(CustomerDTO customer) { 
     this.customer = customer; 
    } 

    //Trying to get copy of object with BeanUtils 
    public final CustomerDTO getCustomer(int customerId){ 
     CustomerDTO origCustomer = _springContext.getBean(CustomerDTO.class); 
     CustomerDTO targetCustomer=null; 
     if("you get customer based on customer id") then "targetCustomer got initialized"; 
     BeanUtils.copyProperties(targetCustomer, origCustomer);//spring BeanUtils 
    } 

    //Trying to add object returned by above method into the list 
    public final List<CustomerDTO> getCustomerList(List<Integer> customerIds){ 
     List<CustomerDTO> customerList = new ArrayList<CustomerDTO>(); 
     for(Integer id:customerIds){ 
      CustomerDTO customer = getCustomer(id); 
      System.out.println("correct output: "+customer.getCustomerId());//getting correct output here 
      customerList.add(customer);//Trying to add copied object in list 
     } 
     for(CustomerDTO customer: customerList){ 
      System.out.println("wrong output: "+customer.getCustomerId());//getting wrong output here 
     } 
     return Collections.unmodifiableList(customerList); 
    } 
} 

В CustomerDTO getCustomer(int customerId) метод, я пытаюсь вернуть копию объекта CustomerDTO с помощью Spring BeanUtils.copyProperties(targetCustomer, origCustomer);. Но когда я добавляю эти скопированные объекты в список в методе List<CustomerDTO> getCustomerList(List<Integer> customerIds), то я получаю странное поведение, как упоминалось в комментариях. Если я удалю BeanUtils.copyProperties(targetCustomer, origCustomer);, поведение будет правильным.

Тестовый пример:

getCustomerList with customerIds =[1,2,3,4] 

С скопированных объектов: BeanUtils.copyProperties(targetCustomer, origCustomer); // пружинные BeanUtils

correct output: 1 
correct output: 2 
correct output: 3 
correct output: 4 
wrong output: 4 
wrong output: 4 
wrong output: 4 
wrong output: 4 

Без скопированных объектов:BeanUtils.copyProperties(targetCustomer, origCustomer); // пружинные BeanUtils

correct output: 1 
correct output: 2 
correct output: 3 
correct output: 4 
wrong output: 1 
wrong output: 2 
wrong output: 3 
wrong output: 4 

Может кто-нибудь, пожалуйста, объясните мне, что является неправильным или возможным объяснением этого поведения?

Обновлено: Цель использования BeanUtils:

Я пытаюсь использовать защитную копию изменяемого объекта перед возвратом объекта CustomerDTO от метода getCustomer(). Поэтому я пытаюсь использовать мелкое клонирование после this post.

обновление: Убрано слово «неизменность», поскольку это было неправильно использовать.

+0

Будет интересно посмотреть, как вы инициализации ваш targetCustomer прежде чем перейти к BeanUtils. Я предполагаю, что вы возвращаете targetCustomer из метода getCustomer (int). При любом изменении вы каждый раз возвращаете «тот же» экземпляр целевого клиента. – Optional

+1

Где непреложный объект? Я не вижу никаких конечных переменных. – tom

+0

@Optional: я извлекаю данные из базы данных для инициализации targetCustomer перед тем, как перейти к Bean Utils. – ritesh

ответ

0
wrong output: 4 
wrong output: 4 
wrong output: 4 
wrong output: 4 

Это может произойти, если список содержит один и тот же объект, а затем почему список содержит тот же объект и как можно работать?

correct output: 1 
correct output: 2 
correct output: 3 
correct output: 4 

origCustomer является содержащий ссылки сказать CustomerDTO @ 60bc92, который одноточечно поддерживается пружиной, поэтому он всегда будет иметь ту же ссылку. Ссылка для targetCustomer изменится. Но BeanUtils.copyProperties (targetCustomer, origCustomer); скопирует свойства targetCustomer в origCustomer означает CustomerDTO @ 60bc92.

for(Integer id:customerIds){ 
      CustomerDTO customer = getCustomer(id); 
      System.out.println("correct output: "+customer.getCustomerId());//getting correct output here 
      customerList.add(customer);//Trying to add copied object in list 
     } 

for(customer ids 1 to 4){ 
     customer will get reference [email protected] and will be updated based on customer ids 
     so it is printing correct values 
     but it is adding same reference [email protected] to the list 
} 

for(CustomerDTO customer: customerList){ 
      System.out.println("wrong output: "+customer.getCustomerId());//getting wrong output here 
     } 

for(all customer object in list which is same object reference and having latest value means 4){ 
     it is printing wrong value as 4 
} 

Теперь почему origCustomer создается из контекста Spring, как

CustomerDTO origCustomer = _springContext.getBean(CustomerDTO.class); 

Поскольку BeanUtils от пружинных потребностей по умолчанию инициализируется пружинный боб.

Решение этой проблемы:

CustomerDTO origCustomer = new CustomerDTO(); 

и использование BeanUtils из org.apache.commons.beanutils.BeanUtils;

1

Вы используете неправильные инструменты.

Ваша проблема в том, что вы перепутали весенние бобы с Java-компонентами.

Весенняя фасоль - одноэлементная, поэтому у вас есть только CustomerDTO в контексте вашей весны. Контекст Spring не является заменой реального DAO.

Используйте либо Map, либо базу данных в DAO и не пытайтесь использовать контекст Spring для операций хранения и извлечения данных.

+0

Не могли бы вы объяснить тестовый пример: «С неизменяемыми объектами»? – ritesh

+0

Цель использования BeanUtils: я пытаюсь использовать защитную копию изменяемого объекта, прежде чем возвращать объект CustomerDTO из метода getCustomer(). Поэтому я стараюсь использовать мелкое клонирование после этого сообщения: http://stackoverflow.com/a/2156367/1544069. Я был бы признателен, если бы вы могли сказать мне правильные инструменты. – ritesh

+1

@ritesh Почему, по-вашему, у вас есть неизменные объекты? Я не вижу в вашей конструкции неизменности. –