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

本秂侑毒 提交于 2019-12-24 15:57:47

问题


I'm working on a API with play 2.5 for an Oracle database. Now I'm trying to use the build in features for JPA in play. On this moment I get the error "No EntityManager bound to this thread. Try wrapping this call in JPAApi.withTransaction, or ensure that the HTTP context is setup on this thread." . This is the code that's responsible for the actual call.

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;}
  }
}

Can someone please explain to me how I can use the build features of play for my JPA calls?


回答1:


You shouldn't have to create an EntityManager. Play is doing this.

So in Play 2.4 and earlier this should just work:

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

JPA.em() gives you the default EntityManager for this thread (https://www.playframework.com/documentation/2.4.x/api/java/index.html).

From Play 2.4 on you can inject Play's JPAApi although JPA still works fine:

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

and then jpaApi.em() (https://www.playframework.com/documentation/2.5.x/api/java/play/db/jpa/JPAApi.html).




回答2:


Everyone thanks for your help but I already solved this problem just a moment ago. I used the following code for my transaction

@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();

the variable api is an instance of JPAApi



来源:https://stackoverflow.com/questions/36128211/how-can-use-jpa-with-play-2-5-without-creating-a-entitymanager-factory-for-each

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!