2011-04-20 22 views
4

我在我的應用程序中使用子資源定位器使用jax-rs restful web服務。但是,在將entityManager傳遞給子資源後,我無法在此子資源中保留任何新對象。如何用jax-rs子資源定位器處理持久化上下文(EntityManager)?

entityManager讓我可以查詢它的數據。

這是我的主要資源:

@Path("/registrations") 
@Stateless 
public class RegistrationsResource { 

    @Context 
    private UriInfo context; 

    @PersistenceContext(unitName="pctx") 
    private EntityManager em; 

    public RegistrationsResource() { 
    } 

    //POST method ommited 

    @Path("{regKey}") 
    public RegistrationResource getRegistrationResource(@PathParam("regKey") 
    String regKey) { 
     return RegistrationResource.getInstance(regKey, em); 
    } 

}

這是我的子資源:

public class RegistrationResource { 

    private String regKey; 
    private EntityManager em; 

    private RegistrationResource(String regKey, EntityManager em) { 
     this.regKey = regKey; 
     this.em = em; 
    } 

    @Path("securityQuestion") 
    @GET 
    public String getQuestion() { 
     return "iamahuman"+regKey; 
    } 

    @Path("securityQuestion") 
    @POST 
    public void postSecurityAnswer(String answer) { 
     if(!answer.equals("iamahuman"+regKey)){ 
      throw new WebApplicationException(Status.BAD_REQUEST); 
     } 

     //Getting this information works properly 
     List<RegistrationEntity> result = em.createNamedQuery("getRegistrationByKey") 
      .setParameter("regKey", regKey).getResultList(); 

     switch(result.size()){ 
      case 0 : 
       throw new WebApplicationException(Status.NOT_FOUND); 
      case 1: 
       break; 
      default: 
       throw new WebApplicationException(Status.INTERNAL_SERVER_ERROR); 
      } 

      RegistrationEntity reg = result.get(0); 
      UserEntity newUser = new UserEntity(); 

      newUser.setHashedPassword(reg.getPwHash(), reg.getSalt()); 
      newUser.setUsername(reg.getUsername()); 
      newUser.setName(reg.getName()); 
      newUser.setSurname(reg.getSurname()); 

      //CRASHES HERE 
      em.persist(newUser); 
    } 
} 

正如你可以看到它需要登記對象從數據庫,創建新用戶註冊並嘗試堅持它。但是,em.persist(newUser)會引發TransactionRequiredException。

我的問題是:我應該如何將EntityManager傳遞給子資源,以便它可以正確保留新對象?

+0

看到http://stackoverflow.com/questions/7456755/jersey-rest-sub-resource-cdi – 2013-08-11 15:38:49

回答

3

可能太遲了,但無論如何... 當你返回你的子資源時,你'離開'無狀態bean。當容器管理事務時,當你從RegistrationsResource返回時,事務被提交。然後

新澤西州將建立你的子資源,但它不是一個無狀態的bean,所以你不會有一個容器管理的事務。因此例外。

我建議你把你的業務邏輯放在一個新的類中,然後你創建一個無狀態bean。在這裏,你做所有的數據庫的東西,然後總是在容器管理的交易中處理。

5

對不起,再挖這件事,但我建議如下:

  • 註釋也子資源作爲@Stateless EJB
  • 將@EJB注入部件領域到父資源類,如所以:
     
        @EJB private RegistrationResource registrationResource; 
    
  • 在 「getRegistrationResource()」
  • ,不叫子資源的構造函數,但返回注入EJB參考:
    public RegistrationResource getRegistrationResource() { 
        return this.registrationResource; 
    }

對於這項工作,但是,你無法通過「@PathParam」作爲構造函數的參數。您必須通過「@Context」或其他@Path聲明在子資源中單獨訪問它。
這使您能夠以與父資源完全相同的方式在子資源中注入EntityManager,您無需傳遞它。