如何在不为我的每个不同调用创建实体管理器工厂的情况下将 JPA 与 play 2.5 一起使用?

How can use JPA with play 2.5 without creating a entitymanager factory for each of my different calls?

我正在为 Oracle 数据库开发 API with play 2.5。现在我正在尝试在游戏中使用 JPA 的内置功能。在这一刻我得到了错误 "No EntityManager bound to this thread. Try wrapping this call in JPAApi.withTransaction, or ensure that the HTTP context is setup on this thread." .这是负责实际调用的代码。

package actors.protocols;

import akka.japi.Option;
import model.DTO.AanleverAfspraakVO;
import model.domain.AanleverAfspraakDO;
import play.db.jpa.JPA;
import play.db.jpa.Transactional;

import javax.persistence.EntityManager;
import javax.persistence.Query;
import java.util.Collection;


public class AanleverAfspraakActorProtocol implements Protocol {

public static class GetAanleverAfspraakByID{
    private int id;

    public GetAanleverAfspraakByID(int id){
        this.id = id;
    }

    /**
     * Get AanleverAfspraak by id
     * @return AanleverAfspraakVO or null
     */
    @Transactional
    public Option<AanleverAfspraakVO> getAanleverAfspraakById(){
        final EntityManager entityManager = JPA.em().getEntityManagerFactory().createEntityManager();
        final Query query = entityManager.createNamedQuery("findbyid");
        query.setParameter("id", id);
        final Collection<AanleverAfspraakDO> resultset = query.getResultList();
        final Option<AanleverAfspraakVO> response;
        Option<AanleverAfspraakVO> response_value = Option.none();
        System.err.println("Size: " + resultset.size());
        if(!resultset.isEmpty()){
            try{
                AanleverAfspraakDO aanleverAfspraakDO = resultset.iterator().next();
                response_value =  Option.some(this.convertAanleverAfspraakBOToVO(aanleverAfspraakDO));
            }catch(Exception e){
                response_value = Option.none();
                e.printStackTrace();
            }
            finally {
                try {
                    entityManager.close();
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }

        }
        response = response_value;
        return  response;
    }

    /**
     * Convert AanleverAfspraakBO to AanleverAfspraakVO
     * @param aanleverAfspraakDO
     * @return
     * @throws NullPointerException
     */
    private AanleverAfspraakVO convertAanleverAfspraakBOToVO(AanleverAfspraakDO aanleverAfspraakDO) throws NullPointerException {
        if(aanleverAfspraakDO == null){
            throw new NullPointerException("aanleverAfspraakDO is null");
        }

        final AanleverAfspraakVO aanleverAfspraakVO = new AanleverAfspraakVO();

        aanleverAfspraakVO.setId(aanleverAfspraakDO.getId());
        aanleverAfspraakVO.setOmschrijving(aanleverAfspraakDO.getOmschrijving());
        aanleverAfspraakVO.setIngangsDatum(aanleverAfspraakDO.getIngangsdatum());
        aanleverAfspraakVO.setEindDatum(aanleverAfspraakDO.getEinddatum());

        return aanleverAfspraakVO;
    }

    public int getId(){return id;}
  }
}

有人可以向我解释一下如何使用 play 的构建功能进行 JPA 调用吗?

您不必创建 EntityManager。游戏就是这样做的。

所以在 Play 2.4 和更早版本 中这应该可以正常工作:

final EntityManager entityManager = JPA.em().createNamedQuery("findbyid");

JPA.em() 为您提供此线程 (https://www.playframework.com/documentation/2.4.x/api/java/index.html) 的默认 EntityManager。

Play 2.4 开始,您可以注入 Play 的 JPAApi,尽管 JPA 仍然可以正常工作:

@Inject
public MyClass(JPAApi api) {
  this.jpaApi = api;
}

然后是 jpaApi.em() (https://www.playframework.com/documentation/2.5.x/api/java/play/db/jpa/JPAApi.html)。

谢谢大家的帮助,我刚才已经解决了这个问题。我在交易中使用了以下代码

@Transactional
public Option<AanleverAfspraakDTO> executeTask() {
    final Option<AanleverAfspraakDTO> response  = api.withTransaction(() -> {
        final Query query = api.em().createNamedQuery("findbyid").setParameter("id", id);
        final Collection<AanleverAfspraakDO> resultset = query.getResultList();

变量api是JPAApi的实例