使用 Java 的 Play Framework 抛出 JPA 事务失败。原因:没有启动的应用程序

Playframeowk with Java throws JPA Transaction failed. caused by: there is no started appliaction

我在 Java 和休眠模式下使用 Play 2.5.7。我需要在应用程序启动时进行一些数据库调用和加载配置。它一直因标题中的错误而失败。 代码,应用程序启动 class:

public class ApplicationStart {
    @Inject
    public ApplicationStart(JPAApi jpaApi, ConfigService configService) {
        jpaApi.withTransaction(() -> {
            configService.reloadConfigs();
        });
    }
}

模块,配置方法:

bind(HibernateDao.class).to(HibernateDaoImpl.class);
bind(ConfigService.class).to(ConfigServiceImpl.class);
bind(ApplicationStart.class).asEagerSingleton();

ConfigureServiceImpl:

@Override
public void reloadConfigs() {
    List<Implementation> impls = hibernateDao.executeQueryForObject(QUERY_GET_IMPLEMENTATIONS, null);
    // process and load the condig.
}

HibernateDaoImpl:

@Override
public <T> List<T> executeQueryForObject(String sql, Map<String, Object> map)
        throws PersistenceException {
    EntityManager em = JPA.em("default");
    try {
        Query query = prepareQuery(em, sql, map);
        List<T> objectList = query.getResultList();
        return objectList;
    } finally {
        em.close();
    }
}

实际错误:

play.api.UnexpectedException: Unexpected exception[CreationException: Unable to create injector, see the following errors:

1) Error injecting constructor, java.lang.RuntimeException: JPA transaction failed
...
Caused by: com.google.inject.CreationException: Unable to create injector, see the following errors:
...
Caused by: java.lang.RuntimeException: JPA transaction failed
...
Caused by: java.lang.RuntimeException: There is no started application
        at scala.sys.package$.error(package.scala:27)
        at play.api.Play$$anonfun$current.apply(Play.scala:86)
        at play.api.Play$$anonfun$current.apply(Play.scala:86)
        at scala.Option.getOrElse(Option.scala:121)
        at play.api.Play$.current(Play.scala:86)
        at play.api.Play.current(Play.scala)
        at play.Play.privateCurrent(Play.java:89)
        at play.Play.application(Play.java:22)
        at play.db.jpa.JPA.jpaApi(JPA.java:48)
        at play.db.jpa.JPA.em(JPA.java:60)

那是因为你使用的是静态JPA.em,而不是注入右class。像在 ApplicationStart class 中那样注入它,它应该可以工作

public class HibernateDaoImpl implements HibernateDao {

    private final JPAApi JPA_API;

    @Inject
    public HibernateDaoImpl(JPAApi api) {
        this.JPA_API = api;    
    }


    // (...)

    @Override
    public <T> List<T> executeQueryForObject(String sql, Map<String, Object> map)
            throws PersistenceException {
        EntityManager em = JPA_API.em("default");
        try {
            Query query = prepareQuery(em, sql, map);
            List<T> objectList = query.getResultList();
            return objectList;
        } finally {
            em.close();
        }
    }
    // (...)
}