我应该抛出EJBException来阻止实体创建

时间:2012-05-10 08:00:29

标签: jsf-2 jpa-2.0

我有以下代码:

JSF Managed Bean:

@ManagedBean(name = "purchaseView")
@ViewScoped
public class PurchaseView implements Serializable {

 @EJB
 private PurchaseService service;
 private Order order;

 // Getter/Setters here

 public void checkoutOrder() {
   // .. some checks for null here, then call service
   service.checkout(order);
 }
}

服务:

@Stateless
public class BuyVoucherService {

 @EJB
 private OrderBean orderBean;
 @EJB
 private ProductBean productBean;

 public boolean checkout(Order order) {
  orderBean.create(order);
  for(int i=0;i<order.getQuantity();i++) {
   Product product = new Product();
   if(someCondition) {
     // don't save anything and
     return false;
   }
   // .. some setter here
   product.setOrder(order);
   productBean.create(product);
  }
  return true;
 }

productBean和orderBean是具有EntityManager和CRUD操作的简单JPA EJB(由Netbeans生成..)。 在上面的服务中,服务返回时,数据库中会保留一些内容。如果出现错误(someCondition == TRUE以上),如果我返回false,则orderBean.save(order)仍会保留数据库中的顺序,我不希望这样。

抛出EJBException并在ManagedBean中捕获它是最好的选择吗?

1 个答案:

答案 0 :(得分:1)

由于您没有明确指定任何事务属性,因此它很可能是Required,但取决于服务器。因此,这两种方法都在同一个事务中,因此在方法中回滚会将更改级联到另一个中。

您也可以尝试将Mandatory属性用于第二种方法,它将确保它需要事务继续进行,否则将导致运行时异常。

    @Resource
    private EJBContext context;

    try{

      if(someCondition) {
          throw SomeBusinessException("Failed, rolling back");
    } 

    }catch(Exception e){
       log(e.getMessage, e) 
       context.setRollbackOnly();
    }

否则,您可以抛出系统异常,这会强制容器回滚正在进行的更改。

    if(someCondition)
        throw SomeBusinessException("Failed, rolling back");

    }catch(Exception e){
        throw new EJBException (e.getMessage(), e);
    }