【问题标题】:JBoss web application - passing the entitymanager as an argument doesn't workJBoss Web 应用程序 - 将 entitymanager 作为参数传递不起作用
【发布时间】:2015-04-14 05:11:48
【问题描述】:

我使用 TicketMonster 教程和应用程序结构开发了一个 JBoss 社交网络 Web 应用程序;我的设计涉及不同类型的帐户权限,许多服务需要检查登录用户的用户帐户详细信息,以及他们想要查看/访问的其他数据。

例如。版主可以查看已禁用的帐户和 cmets,而成员则不能。

对于上面的示例,我正在使用一种方法来创建一个使用用户名检索用户的查询: Query query = entityManager.createQuery("select u from User u where u.username in :userName", User.class); query.setParameter("userName", username); User user = (User) query.getSingleResult(); return user;

由于不同的服务使用该方法,我认为将它放在 ServicesUtility 类中是个好主意,该类在其构造函数中采用 EntityManager,并对其执行查询并返回值。问题是 ServiceUtility 类中的实体管理器不接受传递的 entityManager 并保持为空。同样的方法在 Services 中也可以使用,我对此很好,并且不介意将其添加到 BaseEntityService 父类中,但我只是想知道为什么它不起作用。

更新:这是我的 ServiceUtility 类的代码:

`

public class ServiceUtility {

// @Inject
EntityManager em;

public ServiceUtility(EntityManager entityManager){
    em = entityManager;
}

public User getUserFromUsername(String username){
    try{

        Query query = em.createQuery("select u from User u where u.username in :userName", User.class);
        query.setParameter("userName", username);
        User user = (User) query.getSingleResult();
        return user;
    } catch(Exception e) { //null, no results, constraints violation, exception (all types) - Note: must differentiate between types.
        return null;            
    }
}

public Thread getThreadFromTitle(String title){
    Query query = em.createQuery("select t from Thread t where t.title = :Title");
    query.setParameter("Title", title);
    return (Thread) query.getSingleResult();
}

public Thread getThreadFromId(Long id){
    Query query = em.createQuery("select t from Thread t where t.id = :Id");
    query.setParameter("Id", id);
    return (Thread) query.getSingleResult();
}

public Response badRequestResponse(String message){
    Map<String, Object> responseEntity = new HashMap<String, Object>();
    responseEntity.put("errors", Collections.singletonList(message));
    return Response.status(Response.Status.BAD_REQUEST).entity(responseEntity).build();
}
}

`

更新:

虽然我仍然对这个问题的解决方案非常感兴趣,但我通过对 getSingleInstance 的更改消除了对 ServiceUtility 中需要实体管理器的方法的需求来解决这个问题:

`

@GET
@Path("/{id:[0-9][0-9]*}")
@Produces(MediaType.APPLICATION_JSON)
public T getSingleInstance(@PathParam("id") Long id) {
    return getSingleInstance(entityClass, id);
}

public <X> X getSingleInstance(Class<X> type, Long id){
    final CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
    final CriteriaQuery<X> criteriaQuery = criteriaBuilder.createQuery(type);
    Root<X> root = criteriaQuery.from(type);
    Predicate condition = criteriaBuilder.equal(root.get("id"), id);
    criteriaQuery.select(criteriaQuery.getSelection()).where(condition);
    return entityManager.createQuery(criteriaQuery).getSingleResult();
}

`

【问题讨论】:

    标签: java web-applications jboss


    【解决方案1】:

    最好使用依赖注入-@Inject(首选)或@PersistenceContext,将EntityManager 依赖注入ServicesUtility。在 Java EE 中,构造函数注入器不是字段注入的首选/不受支持,因此使用字段注入是有意义的。

    只要 bean ServicesUtility 的生命周期由容器(CDI 容器或其他)管理,其中的 EntityManager 字段在典型的方法调用期间不会为空。

    TicketMonster 中的There is a CDI producer method,它演示了如何编写生产者方法来生成EntityManager。 CDI 容器将使用此生产者将EntityManager 注入开发人员(您)声明的任何所需注入点;例如,this is how the BaseEntityService receives it's EntityManager reference

    【讨论】:

    • 我已经在使用 Resources.java,并已将其用于在我的 BaseEntityService 类中注入 EntityManager;使用 @Inject 在 ServiceUtility 中也不起作用,如您所见,我已在上面代码的字段声明中将其注释掉。它仍然为我的 EntityManager 提供了一个空值,并在其上抛出了 NullPointerException。这个问题还有其他原因吗?
    • 顺便说一句,我不懂 Resources.java
    猜你喜欢
    • 2020-01-19
    • 1970-01-01
    • 2021-03-05
    • 2015-06-03
    • 1970-01-01
    • 2018-11-23
    • 2016-09-22
    • 2020-04-06
    • 1970-01-01
    相关资源
    最近更新 更多