我有一个使用 Quarkus Hibernate ORM 的 Quarkus 微服务,并且想要创建一个从数据库中读取值的指标仪表。不幸的是,每当我尝试读取该值时,Hibernate 事务处理程序都会抛出一个javax.enterprise.context.ContextNotActiveException
.
javax.enterprise.context.ContextNotActiveException
at io.quarkus.arc.impl.ClientProxies.getDelegate(ClientProxies.java:46)
at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.arc$delegate(Unknown Source)
at io.quarkus.hibernate.orm.runtime.RequestScopedSessionHolder_ClientProxy.getOrCreateSession(Unknown Source)
at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.acquireSession(TransactionScopedSession.java:104)
at io.quarkus.hibernate.orm.runtime.session.TransactionScopedSession.createNativeQuery(TransactionScopedSession.java:408)
at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createNativeQuery(ForwardingSession.java:208)
at io.quarkus.hibernate.orm.runtime.session.ForwardingSession.createNativeQuery(ForwardingSession.java:47)
at org.hibernate.Session_5b93bee577ae2f8d76647de04cfab36afbf52958_Synthetic_ClientProxy.createNativeQuery(Unknown Source)
...
这是我使用 Smallrye 指标的代码:
@ApplicationScoped
public class IssueRepository {
@Inject
EntityManager em;
@Gauge(name = "issues.total", unit = MetricUnits.NONE)
long countIssues() {
// query for testing
Query nativeQuery = em.createNativeQuery("SELECT 1", Long.class);
return (Long) nativeQuery.getSingleResult();
}
}
这是我尝试使用 Quarkus Micrometer 注册表:
@ApplicationScoped
public class IssueRepository {
@Inject
EntityManager em;
@Inject
MeterRegistry meterRegistry;
@PostConstruct
void initialize() {
Gauge.builder("issues.total", this::countIssues).register(meterRegistry);
}
private long countIssues() {
// query for testing
Query nativeQuery = em.createNativeQuery("SELECT 1", Long.class);
return (Long) nativeQuery.getSingleResult();
}
}
两种方法都不起作用,因为两者都ContextNotActiveException
被抛出。似乎请求上下文没有传播(显然没有),没有它实体管理器就无法工作。
那么从数据库中读取仪表的正确方法是什么?
更新:
@Transactional
通过将注释添加到仪表方法,我可以使用 Smallrye 指标。
@ApplicationScoped
public class IssueRepository {
@Inject
EntityManager em;
@Gauge(name = "issues.total", unit = MetricUnits.NONE)
@Transactional
long countIssues() {
// query for testing
Query nativeQuery = em.createNativeQuery("SELECT 1", Long.class);
return (Long) nativeQuery.getSingleResult();
}
}