Przy dodawaniu obiektu do listy, obiekt podmienia resztę obiektów w liście.

0

Cześć,

Uczę się JSF i mam pewien problem, którego nie mogę namierzyć.

W formularzu tworzę nowe produkty. Po kliknięciu w command button wywołuje się metoda która ma dodać ten produkt do listy. Lista ta znajduje się w singletonowym komponencie.

Problem polega na tym, że gdy dodaję jakiś obiekt to on zastępuję wszystkie inne obiekty w liście. Np. mam w liście obiekty: "Komputer", "Tv" i dodaję nowy obiekt "Książka" i teraz w liście mam: "Książka","Książka","Książka".

Mój prosty kontroller:

@Named
public class AdminController {

	@Inject
	private ProductService productService;
	
	public void createProduct(Product product) {

		productService.createProduct(product);
	}
}

Serwis:

@Named
@SessionScoped
public class ProductService implements Serializable {

	private static final long serialVersionUID = -2542942450639054245L;
	
	@Inject
	private Warehouse warehouse;
	
	@Named
	@Produces
	public List<Product> getProductList() {
		return warehouse.getProductList();
	}
	
	public void createProduct(Product product) {
		warehouse.addProduct(product);
	}
}

Singletonowy magazyn:

@Singleton
@Startup
public class Warehouse {

	private List<Product> productList;
	
	@PostConstruct
	public void init() {
		productList = new LinkedList<Product>();
	}
	
	@Lock(LockType.READ)
	public List<Product> getProductList() {
		return productList;
	}
	
	@Lock(LockType.WRITE)
	public void addProduct(Product product) {
		productList.add(product);
	}
}

I klasa reprezentująca produkt.

@Named
@RequestScoped
public class Product {

	private int id;
	private String name;
	private double price;
	private boolean enabled;

      //geters and seters
}
0

Przed każdym dodaniem do listy musisz utworzyć nowy produkt (operator new).

0

Ale jak utworzyć nowy obiekt. Przecież ja tu wysyłam obiekt utworzony na stronie xhtml więc nie mogę tworzyć nowego obiektu.

Ok rozwiązałem to w ten sposób:

        @Named
	@Produces
	private Product newProduct;
	
	@PostConstruct
	public void post() {
		newProduct = new Product();
	}
	
	public void createProduct() {

		productService.createProduct(newProduct);
	}

Dzięki za pomoc. Chociaż i tak dalej nie rozumiem czemu to poprzednie nie działało a to działa :-(

1

Do listy dodawałeś referencję do obiektu. Po kolei:

  • tworzysz obiekt klasy product, on ma referencję Product@15686a7, ta referencja wskazuje na zawartość "Komputer"
  • dodajesz referencję do kolekcji, kolekcja zawiera jedną referencję Product@15686a7,
  • nie tworzysz nowego obiektu, ale zmieniasz cechy obiektu wskazywanego przez referencję, np. na "Tv",
  • dodajesz referencję do kolekcji, kolekcja zawiera dwie identyczne referencje Product@15686a7 i Product@15686a7
    ...
    Jeśli użyjesz operatora new, to powstanie nowa referencja.
import java.util.*;
public class Test
{
    public static void main(String[] args)
    {
        new Test();
    }
    public Test()
    {
        List<Product> lista = new ArrayList<Product>();
        Product pr = new Product("Jasiu"); 
        lista.add(pr);     
        pr.content = "Stasiu";
        lista.add(pr);
        for(Product product:lista)
        {
            System.out.println(product+" "+product.opis());
        }
        System.out.println();
        lista.clear();
        pr = new Product("Jasiu"); 
        lista.add(pr);     
        pr = new Product("Stasiu");
        lista.add(pr);
        for(Product product:lista)
        {
            System.out.println(product+" "+product.opis());
        }        
    }
    class Product
    {
        public String content;
        public Product(String content)
        {
            this.content = content;
        }
        public String opis()
        {
            return content;
        }
    }
}
0

No faktycznie problem był z referencją. Wiem do czego służy operator new, ale ja używałem stron JSF i tam tworzyłem produkt jak bean.

Dzięki wielkie za pomoc.

1 użytkowników online, w tym zalogowanych: 0, gości: 1