问题
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