Question

Im trying out an example with EJB Session Beans. I wanna see the differences them. My basic projects diagram is below ;

http://img109.imageshack.us/img109/8262/85220418.png

Project is like a shopping cart. When i invoke to the managed bean to get result of added Urun objects via injected EJB, result list must be last Urun object. Cause my EJB is @Stateless bean. But, when i run the application, it keeps the all new added Urun object. But it is Stateless, it must keep the last Urun object in every action. And then, when i open the application page in other web browser, it list the before added Urun object's list. But managed bean and Ejb is Stateless in my model. But it acts a Singleton bean. Where is my problem?

@Stateless
public class AlisverisSepetiEJB {

    List<Urun> urunler=new ArrayList<>();

    public List<Urun> getUrunler() {
        return urunler;
    }

    public void setUrunler(List<Urun> urunler) {
        this.urunler = urunler;
    }

    public void urunEkle(Urun urun){
        urunler.add(urun);
    }

}

@ManagedBean(name="bean")
@RequestScoped
public class JSFYonetimliNesne {

    public JSFYonetimliNesne(){
        System.out.println("Yönetimli nesne çalıştı");
    }

   @EJB
   AlisverisSepetiEJB alisverisSepeti;

   Urun urun=new Urun();
   List<Urun> urunler;


    public List<Urun> getUrunler() {
        return alisverisSepeti.getUrunler();
    }

    public void setUrunler(List<Urun> urunler) {
        this.urunler = urunler;
    }

    public Urun getUrun() {
        return urun;
    }

    public void setUrun(Urun urun) {
        this.urun = urun;
    }

    public void sepeteKoy(){
        alisverisSepeti.urunEkle(urun);
        urun=new Urun();
    }

}

public class Urun {

   String urunAdi;
   Long fiyat;
   Long gramaj;

    public Long getFiyat() {
        return fiyat;
    }

    public void setFiyat(Long fiyat) {
        this.fiyat = fiyat;
    }

    public Long getGramaj() {
        return gramaj;
    }

    public void setGramaj(Long gramaj) {
        this.gramaj = gramaj;
    }

    public String getUrunAdi() {
        return urunAdi;
    }

    public void setUrunAdi(String urunAdi) {
        this.urunAdi = urunAdi;
    }

}

<?xml version="1.0" encoding="UTF-8"?>

<!DOCTYPE html>
<html xmlns="http://www.w3.org/1999/xhtml"
      xmlns:h="http://java.sun.com/jsf/html"
      xmlns:f="http://java.sun.com/jsf/core">
    <h:head>
        <title>Alışveriş Sepeti</title>
    </h:head>
    <h:body>
        Alışveriş Sepeti
        <h:form>

            <h:panelGrid columns="2">
            <h:outputLabel value="Ürün adı : "/>
            <h:inputText value="#{bean.urun.urunAdi}"/>
            <h:outputLabel value="Ürün fiyatı : "/>
            <h:inputText value="#{bean.urun.fiyat}"/>
            <h:outputLabel value="ÜRün gramajı : "/>
            <h:inputText value="#{bean.urun.gramaj}"/>
            </h:panelGrid>

            <h:commandButton action="#{bean.sepeteKoy}" value="Sepete Ekle"/>

            <br><h:outputLabel value="Sepetteki Ürünler"/></br>


            <h:dataTable value="#{bean.urunler}" var="item" border="1">

            <h:column >
                <f:facet name="header">
                    <h:outputLabel value="Ürün adı"/>
                </f:facet>
            <h:outputText value="#{item.urunAdi}"/>
            </h:column>

            <h:column >
                <f:facet name="header">
                    <h:outputLabel value="Ürün fiyatı"/>
                </f:facet>
            <h:outputText value="#{item.fiyat}"/>
            </h:column>

            <h:column >
                <f:facet name="header">
                    <h:outputLabel value="Ürün gramajı"/>
                </f:facet>
            <h:outputText value="#{item.gramaj}"/>
            </h:column>

            </h:dataTable>

        </h:form>

    </h:body>
</html>
Was it helpful?

Solution

It's quite possible that the same instance of AlisverisSepetiEJB is being shared between invocations (the container can do this, it's perfectly legal). Precisely because of the stateless nature of a @Stateless EJB, you should not declare instance attributes in it!

Remove the List<Urun> urunler = new ArrayList<>(); declaration and all associated methods, think of a stateless bean as a class where all its methods are static - meaning, that they can't use any instance attributes and must be completely independent of instance data; if any state needs to be maintained between calls, then it must be passed along as parameters from the point where the EJB is being invoked. The only instance variables allowed in a @Stateless EJB are attributes which are themselves stateless and/or immutable.

If you need to maintain the state of the shopping cart between invocations, you'll have to keep it elsewhere in a stateful context (say, the Session context of a web application) or mark the EJB as @Stateful.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top