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