【问题标题】:Cannot persist in stateful session bean无法在有状态会话 bean 中持续存在
【发布时间】:2019-09-23 05:01:12
【问题描述】:

我正在使用 Java EE 应用程序的有状态会话 bean 方法制作购物车。我的计划是,在用户单击“结帐”按钮后,订单将被添加到数据库中。但是,数据库中的订单没有更新。

ShoppingCartFacade.java

@Stateful
public class ShoppingCartFacade implements ShoppingCartFacadeLocal {

    @PersistenceContext(unitName = "DProject-ejbPU", type = PersistenceContextType.EXTENDED)
    private EntityManager em;

    private void create(Tickettable tickettable) {
        em.persist(tickettable);
    }

    private ArrayList<Tickettable> ticketCart;

    @PostConstruct
    private void initializeBean(){
        ticketCart = new ArrayList<>();
    }

    @Override
    public boolean add(Tickettable tickettable) {
        boolean result = false;

        //Set the correct user and showtime table
        tickettable.setUserid(this.getUsertableFrom(tickettable.getUserid().getUserid()));
        tickettable.setShowtimeid(this.getShowtimetableFrom(tickettable.getShowtimeid().getShowtimeid()));

        try {
            //Already have ticket for this showtime
            for (Tickettable ticket : ticketCart) {
                if (ticket.getShowtimeid().getShowtimeid().equals(tickettable.getShowtimeid().getShowtimeid())) {
                    ticket.setQuantity(ticket.getQuantity() + tickettable.getQuantity());
                    result = true;
                }
            }
            //New ticket
            if (!result) {
                ticketCart.add(tickettable);
                result = true;
            }
        } catch (Exception ex) {
        }
        return result;
    }

    @Override
    public ArrayList<Tickettable> getCart() {
        return ticketCart;
    }

    @Override
    public boolean checkOut() {
        try {
            for (Tickettable ticket : ticketCart) {
                create(ticket);
            }
            ticketCart.clear();
            return true;
        } catch (Exception e) {
        }
        return false;
    }

    private Usertable getUsertableFrom(String userId) {
        Usertable u = em.getReference(Usertable.class, userId);
        return u;
    }

    private Showtimetable getShowtimetableFrom(String showtimeId) {
        Showtimetable s = em.getReference(Showtimetable.class, showtimeId);
        return s;
    }

    @Remove
    public void remove() {
        ticketCart = null;
    }
}

ShoppingCartManagement.java

@Stateful
public class ShoppingCartManagement implements ShoppingCartManagementRemote {
    @EJB
    private ShoppingCartFacadeLocal shoppingCartFacade;

    @Override
    @PermitAll
    public boolean add(TicketDTO ticketDTO) {
       if (ticketDTO == null) {
            // just in case
            return false;
        }

        // convert to entity
        Tickettable ticket = Utility.ticketDTO2Entity(ticketDTO);
        // add one
        return shoppingCartFacade.add(ticket);
    }

    @Override
    @PermitAll
    public ArrayList<TicketDTO> getCart() {
        try {
            ArrayList<Tickettable> alst = shoppingCartFacade.getCart();

            if (alst.isEmpty()) {
                //not found
                return null;
            } else {
                ArrayList<TicketDTO> alsDTO = new ArrayList<>(alst.size());
                for (Tickettable stt : alst) {
                    TicketDTO stDTO = Utility.ticketEntity2DTO(stt);
                    alsDTO.add(stDTO);
                }
                return alsDTO;
            }
        } catch (NullPointerException e) {
            throw e;
        }
    }

    @Override
    @PermitAll
    public boolean checkOut() {
        return shoppingCartFacade.checkOut();
    }
}

战争中的ShoppingCartManagedBean.java

@Named(value = "shoppingCartManagedBean")
@RequestScoped
public class ShoppingCartManagedBean implements Serializable{

 .....

    @EJB
    private ShoppingCartManagementRemote shoppingCartManagement;

    public String addTicket(){

        this.quantity += 1;

        UserDTO u = new UserDTO(userId,"","","","","");
        ShowtimeDTO s = new ShowtimeDTO(showtimeId,"","","","","");

        TicketDTO t = new TicketDTO("111111",u,s,Integer.toString(this.quantity));
        //carts = shoppingCartManagement.getCart();
        boolean result =  shoppingCartManagement.add(t);
        if(result){
            return "success";
        }
        return "failure";
    }

    public String checkout(){
        /*return shoppingCartManagement.checkOut();*/

        boolean result = shoppingCartManagement.checkOut(); 
        if(result) return "success";
        return "failure";
    }
}

****************************更新********************

我刚刚做了测试。 ShoppingCartFacade.java 中的 cartList 为空。

【问题讨论】:

  • 类中的ShoppingCartFacade 方法add()checkout() 正在吞噬异常,因此如果抛出异常,您对此一无所知。

标签: java jakarta-ee netbeans ejb stateful


【解决方案1】:

您需要了解您正在使用的各种 bean 的生命周期管理。

@Stateful bean 没有与 servlet/JSF 会话隐式关联。

将为每个传入请求创建一个新的ShoppingCartManagedBean 实例,因为它是@RequestScoped。此实例将自动获得对 ShoppingCartManagement 新实例的引用,而后者又将获得对 ShoppingCartFacade 新实例的引用。

您需要:

  1. ShoppingCartManagedBean 更改为@SessionScoped,或者

  2. 创建一个@SessionScoped 外观,它委托给ShoppingCartManagement 引用并注入它来代替EJB。

这些方法中的任何一个都会将您的有状态会话 bean 与 servlet/JSF 会话相关联。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2013-08-02
    • 2013-08-27
    • 2012-08-17
    • 1970-01-01
    • 2011-03-31
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多