【问题标题】:Stateful EJB not retaining information有状态的 EJB 不保留信息
【发布时间】:2010-04-28 16:05:08
【问题描述】:

我创建了一个简单的购物车。它可以存储一个项目,我可以返回页面并且该项目仍然存在,但是一旦我将另一个项目添加到购物车,它就会重置并只存储那个项目。有什么想法吗?

谢谢

@Stateful(name="CartSessionBean")
@Remote(CartSession.class)
public class CartSessionBean implements CartSession, java.io.Serializable {

    private Cart items;

    @Init
    public void create() {
        items = new Cart();
    }

    public void add(Book item, int qty) {

        items.addItem(item, qty);

    }

Cart.java

@Entity

@Table(name = "购物车") 公共类 Cart 实现 java.io.Serializable {

@Id @GeneratedValue
@Column(name="id")
private int id;

@Column(name = "total")
private Double total;

@OneToMany(mappedBy="cart")
private Set<Item> items;

public Cart(){
    // not valid?

}

//setters and getters

public int getOrder(){
    return id;
}

public void setOrder(int order){
    this.id = order;
}

public Double getTotal(){
    return total;
}

public void setTotal(Double q){
    this.total = q;
}

public Set<Item> getItems(){
    return this.items;
}

public void setItems(Set<Item> i){
    this.items = i;
}

public void addItem(Book b, int qty) {

    if(items == null) {
        items = new HashSet();
    }

    Item i = new Item();
    i.setBook(b);
    i.setQty(qty);

    this.items.add(i);
}

public void removeItem(Item id) {
    this.items.remove(id);
}

public void emptyCart() {
    this.items.clear();
}

}

小服务程序

public class ServletCart extends HttpServlet {

    private Set<Item> items;

    @Override
    public void doGet(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        // NO need.

        // DO WE HAVE A REMOVE REQUEST??

        if (items == null) {

            try {
                InitialContext context = new InitialContext();
                CartSession cartitems = (CartSession) context.lookup("CartSessionBean/remote");
                items = cartitems.getItems();
            } catch (NamingException e) {
                throw new ServletException("JNDI problem", e);
            }

        }

        RequestDispatcher view = request.getRequestDispatcher("cart.jsp");
        request.setAttribute("items", items);
        request.setAttribute("size", items.size());
        view.forward(request, response);
    }

    @Override
    public void doPost(HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {

        // Add a book :s/

        String isbn = request.getParameter("isbn"); // Does this ISBN exsit?
        int quantity = Integer.parseInt(request.getParameter("qty")); // Is this a number ?

        Book bk;

        try {
            InitialContext context = new InitialContext();
            BookSession guestbookSession = (BookSession) context.lookup("BookSessionBean/remote");
            bk = guestbookSession.getBook(isbn);

            CartSession cartitems = (CartSession) context.lookup("CartSessionBean/remote");
            cartitems.add(bk, quantity);

            this.items = cartitems.getItems();

        } catch (NamingException e) {
            throw new ServletException("JNDI problem", e);
        }

        request.setAttribute("response", bk.getBookTitle() + " Added.");

        doGet(request, response);

    }
}

【问题讨论】:

  • 购物车类是什么样的?您能否在“create/init”方法中添加一些日志记录代码,以查看您的购物车是否正在重新初始化?
  • 每次添加一本书时,都会调用 create/init。导致重置。
  • 请显示获取 CartSessionBean 以将条目添加到购物车的调用(servlet/JSP?)代码。我假设调用代码将 bean 存储在 HttpSession 中,而不是重复查找 SFSB 工厂?

标签: java ejb


【解决方案1】:

显示的代码存在几个问题:

  1. 您不能在没有同步的情况下将实例变量存储在 servlet 中。对 servlet 的所有请求共享同一个实例,因此实例变量将被共享。
  2. CartSession.getItems 是一个远程方法调用,所以返回的项目列表是通过值复制和传递的。看起来您可能一直在尝试解决这个问题?
  3. 每次调用 context.lookup("CartSessionBean/remote") 都会创建一个有状态会话 bean 的新实例。

您需要执行以下操作:从 HttpServletRequest 查找或创建一个 HttpSession,在会话上查找或创建购物车实例,然后使用购物车会话 bean。

【讨论】:

    猜你喜欢
    • 2012-12-28
    • 2011-08-05
    • 1970-01-01
    • 2016-09-03
    • 2012-05-07
    • 1970-01-01
    • 1970-01-01
    • 2017-02-12
    • 1970-01-01
    相关资源
    最近更新 更多