Hibernate Grails-如何在服务中保存域对象?
我有一个服务,在其中一个函数中,我正在创建一个域对象并试图保存它。Hibernate Grails-如何在服务中保存域对象?,hibernate,session,grails,service,grails-domain-class,Hibernate,Session,Grails,Service,Grails Domain Class,我有一个服务,在其中一个函数中,我正在创建一个域对象并试图保存它。 当它到达保存部分时,我得到了错误 没有绑定到线程的休眠会话, 和配置不允许 在这里创建非事务性的 为了在服务中保存域对象,我需要做什么。互联网上的所有东西都让它看起来像这样,应该就行了 编辑: 其他详情: 我偶然发现了这篇文章 这是一个类似的场景。我的服务被第三方API调用 编辑: 我解释得不太清楚。下面是更完整的代码 import org.springframework.beans.factory.InitializingB
当它到达保存部分时,我得到了错误 没有绑定到线程的休眠会话, 和配置不允许 在这里创建非事务性的 为了在服务中保存域对象,我需要做什么。互联网上的所有东西都让它看起来像这样,应该就行了 编辑:
其他详情: 我偶然发现了这篇文章
这是一个类似的场景。我的服务被第三方API调用 编辑:
我解释得不太清楚。下面是更完整的代码
import org.springframework.beans.factory.InitializingBean
import com.ib.client.EWrapper;
class BrokerService implements InitializingBean, EWrapper{
static transactional = true
private EClientSocket m_client
private boolean m_disconnectInProgress = false
void afterPropertiesSet(){
// this.setting = grailsApplication1.config.setting
m_client = new EClientSocket(this)
m_disconnectInProgress = false
connect()
}
def boolean connect() {
m_client.eConnect()
if (m_client.isConnected())
return true
return false
}
def void historicalData(int reqId, String date, double open,
double high, double low, double close, int volume, int count,
double WAP, boolean hasGaps)
{
HistoricalContractData.withNewSession{session->
println ' just before object create'
def hcd = new sbi.investments.HistoricalContractData()
hcd.hc_id = reqId
hcd.data_date = new Date().parse('yyyyMMdd', date.replace('finished-', ''))
hcd.open = open
hcd.high = high
hcd.low = low
hcd.close = close
hcd.volume =volume
hcd.trade_count =count
hcd.wap = WAP
hcd.has_gaps = hasGaps.toString()
println ' just before save'
hcd.save()
if(hcd.hasErrors()){
println '=========== ERROR! ============'
println hcd.errors
}
}
}
}
第三方API多次调用historicalData。使用上面的代码,它正在保存第一条记录,但在第二条记录上,我得到了错误:
无法打开休眠会话;
嵌套异常是
org.hibernate.SessionException:
会议结束了
编辑:因此,我想通过更多的阅读了解正在发生的事情。
从控制器调用时,通常会将hibernate会话注入服务。
由于historicalData是从第三方应用程序调用的,而不是通过控制器调用的,因此服务中没有注入hibernate会话,因此它会抱怨会话已关闭 因此,我认为真正的问题可能是,如果没有从控制器调用服务,如何创建新的hibernate会话以保存grails域模型对象(即HistoricalContractData)。
如上所述,withNewSession不起作用。我应该这样使用SessionFactory吗?
(无法将链接发布到源,因为堆栈溢出不喜欢它)
我尝试过这样做,但不知道如何使用会话对象来保存HistoricalContractData对象。您需要为您的服务指定一个事务上下文。确保您的Grails服务已经完成 另一个Grails服务链接:
您需要为您的服务指定一个事务上下文。确保您的Grails服务已经完成 另一个Grails服务链接:
默认情况下,服务方法应该是事务性的,并且有一个会话。如果不是这样,那么您可能没有遵循Grails约定:
AnyDomainObject.withTransaction{txStatus->
// do stuff like save here
}
或使用创建新会话
AnyDomainObject.withNewSession{session->
// do stuff here
}
您的代码没有闭包所需的“箭头”
编辑,对于您的更新,您应该签出
关于如何使用会话。基本上,你应该能够做到
session.save(hcd)
另外,在调用sessionFactory.getCurrentSession()之后,您可能可以像grails中的普通方法一样执行hcd.save()——我认为这可能有效的原因是,该方法应该创建一个新会话,并通过threadlocal将其绑定到当前线程 默认情况下,服务方法应该是事务性的,并且具有会话。如果不是这样,那么您可能没有遵循Grails约定:
AnyDomainObject.withTransaction{txStatus->
// do stuff like save here
}
或使用创建新会话
AnyDomainObject.withNewSession{session->
// do stuff here
}
您的代码没有闭包所需的“箭头”
编辑,对于您的更新,您应该签出
关于如何使用会话。基本上,你应该能够做到
session.save(hcd)
另外,在调用sessionFactory.getCurrentSession()之后,您可能可以像grails中的普通方法一样执行hcd.save()——我认为这可能有效的原因是,该方法应该创建一个新会话,并通过threadlocal将其绑定到当前线程 你是说服务范围吗?我的服务是单身。你能帮我指出一些例子或文件吗?感谢您帮助我更具体地了解您所说的“这种方式”是什么意思。我最初是按照那个教程创建我的服务的,但是关于这个主题的文档似乎很少。如果不查看您的所有代码,就无法更具体地说了。坦率地说,我不知道我想花时间。我今晚要出去!哈哈,很公平。谢天谢地,我也可以说我今晚要出去。明天我会发布更完整的代码。新年快乐!你是说服务范围吗?我的服务是单身。你能帮我指出一些例子或文件吗?感谢您帮助我更具体地了解您所说的“这种方式”是什么意思。我最初是按照那个教程创建我的服务的,但是关于这个主题的文档似乎很少。如果不查看您的所有代码,就无法更具体地说了。坦率地说,我不知道我想花时间。我今晚要出去!哈哈,很公平。谢天谢地,我也可以说我今晚要出去。明天我会发布更完整的代码。新年快乐@谢谢。我想我遵守了大多数惯例#4否,因为服务中的函数historicalData正在被第三方API(另一个应用程序)调用。@w-另一个应用程序如何获得您的服务?如果它通过web请求(例如RESTAPI)调用它,那么您应该在服务前面有一个控制器。不管怎样,如我所示添加箭头应该会有所帮助。@hvgotcodes,正如您所看到的