@Stateless Session Bean充当@Singleton Bean

时间:2022-10-30 09:23:05

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

我试着用EJB Session Beans做一个例子。我想看看它们之间的差异。我的基本项目图如下;

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

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?

项目就像一个购物车。当我调用托管bean以通过注入的EJB获取添加的Urun对象的结果时,结果列表必须是最后一个Urun对象。因为我的EJB是@Stateless bean。但是,当我运行应用程序时,它会保留所有新添加的Urun对象。但它是无状态的,它必须在每个动作中保留最后一个Urun对象。然后,当我在其他Web浏览器中打开应用程序页面时,它会列出之前添加的Urun对象的列表。但是在我的模型中,托管bean和Ejb是无状态的。但它扮演一个Singleton bean。我的问题在哪里?

@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>

1 个解决方案

#1


5  

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!

很有可能在调用之间共享同一个AlisverisSepetiEJB实例(容器可以做到这一点,它完全合法)。正是由于@Stateless EJB的无状态特性,您不应该在其中声明实例属性!

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.

删除List urunler = new ArrayList <>();声明和所有相关方法,将无状态bean视为一个类,其中所有方法都是静态的 - 这意味着它们不能使用任何实例属性,并且必须完全独立于实例数据;如果需要在调用之间维护任何状态,则必须将其作为参数从调用EJB的位置传递。 @Stateless EJB中允许的唯一实例变量是本身无状态和/或不可变的属性。

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.

如果您需要在调用之间维护购物车的状态,则必须将其保留在有状态上下文中(例如,Web应用程序的Session上下文)或将EJB标记为@Stateful。

#1


5  

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!

很有可能在调用之间共享同一个AlisverisSepetiEJB实例(容器可以做到这一点,它完全合法)。正是由于@Stateless EJB的无状态特性,您不应该在其中声明实例属性!

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.

删除List urunler = new ArrayList <>();声明和所有相关方法,将无状态bean视为一个类,其中所有方法都是静态的 - 这意味着它们不能使用任何实例属性,并且必须完全独立于实例数据;如果需要在调用之间维护任何状态,则必须将其作为参数从调用EJB的位置传递。 @Stateless EJB中允许的唯一实例变量是本身无状态和/或不可变的属性。

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.

如果您需要在调用之间维护购物车的状态,则必须将其保留在有状态上下文中(例如,Web应用程序的Session上下文)或将EJB标记为@Stateful。