我有一个使用JMS插件的Grails 2.2应用程序(使用版本1.3)。
我遇到的情况是,当我的服务器启动时,JMS插件会初始化,并且监听器服务会在服务器完成设置之前抓取队列中的所有等待消息。
具体来说,它会在代码中遇到第一个hibernate查询并因以下错误而失败:
| Error 2014-10-14 11:06:56,535 [ruleInputDataListenerJmsListenerContainer-1] ERROR drms.RuleInputDataListenerService - Message Exception: Failed to process JMS Message.
groovy.lang.MissingMethodException: No signature of method: au.edu.csu.drms.Field.executeQuery() is applicable for argument types: () values: []
Possible solutions: executeQuery(java.lang.String), executeQuery(java.lang.String, java.util.Collection), executeQuery(java.lang.String, java.util.Map), executeQuery(java.lang.String, java.util.Collection, java.util.Map), executeQuery(java.lang.String, java.util.Map, java.util.Map)
有问题的代码是正确的:
String query = "SELECT f FROM field f WHERE (attributeName = :attributeName AND entityName = :entityName)"
def fieldList = Field.executeQuery(query, [attributeName: _attributeName, entityName: _entityName])
据我所知,当JMS侦听器执行onMessage
方法时,hibernate没有被初始化。它也发生在withCriteria
或任何其他hibernate查询方法中。
只有在服务器启动时队列中有消息并且每个消息等待失败时才会发生这种情况。一旦队列完成并处理新消息,它就可以正常工作。
有没有办法让hibernate及时初始化或延迟执行Listener服务(很像具有启动延迟计时器的Quartz插件)?
更新:
我不使用bean配置,因为它是一个守护进程类型的应用程序 - 我们没有要定义的bean。
有没有办法使用@DependsOn并让我的监听器依赖于Hibernate本身?
答案 0 :(得分:1)
假设您有以下EntityManagerFactory配置:
<bean id="entityManagerFactory" class="org.springframework.orm.jpa.LocalContainerEntityManagerFactoryBean">
<property name="jpaDialect" ref="jpaDialect"/>
</bean>
您需要使您的JMS连接工厂依赖于entityManagerFactory:
<bean id="jmsConnectionFactory" class="org.apache.activemq.pool.PooledConnectionFactory"
destroy-method="stop" depends-on="jmsBroker, entityManagerFactory">
<property name="connectionFactory" ref="activeMQConnectionFactory"/>
</bean>
答案 1 :(得分:0)
不幸的是,由于我的应用程序的性质(没有bean配置),@DependsOn
符号不起作用。
鉴于Grails JMS插件存在一些错误/问题,我的问题的解决方案是在处理JMS消息之前使用以下代码:
def onMessage(msg) {
try {
Rule.withNewTransaction {
log.info("Hibernate is up and running!")
}
} catch (Exception e) {
resendMessage(msg)
}
// rest of code...
}
我使用事务测试Hibernate是否已完全初始化(已经测试过,当JMS侦听器在启动时触发时),如果它捕获异常,它会将消息重新发送回队列以进行重新处理