使用 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();
}
}
// (...)
}
我在 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();
}
}
// (...)
}