Grails 我可以从关联(joinTable)中恢复缺少的数据吗
我读了很多帖子和文档,肯定是遗漏了什么 在我的应用程序(下面的模型)中,我遇到了一个似乎超出我控制范围的数据问题,在联接表JOBORDERCATEGORIES中有一个categoryId,而在CATEGORY表中没有相应的行。我通过JobOrder中的getJobCategories()访问类别数据。当我的类别表缺少引用行时,会产生以下错误:Grails 我可以从关联(joinTable)中恢复缺少的数据吗,grails,many-to-many,jointable,Grails,Many To Many,Jointable,我读了很多帖子和文档,肯定是遗漏了什么 在我的应用程序(下面的模型)中,我遇到了一个似乎超出我控制范围的数据问题,在联接表JOBORDERCATEGORIES中有一个categoryId,而在CATEGORY表中没有相应的行。我通过JobOrder中的getJobCategories()访问类别数据。当我的类别表缺少引用行时,会产生以下错误: 2012-03-07 08:02:10,223 [quartzScheduler_Worker-1] ERROR listeners.SessionBin
2012-03-07 08:02:10,223 [quartzScheduler_Worker-1] ERROR listeners.SessionBinderJobListener - Cannot flush Hibernate Sesssion, error will be ignored
org.hibernate.ObjectNotFoundException: No row with the given identifier exists: [com.matrixres.domain.Category#416191]
我的代码停止了
我曾尝试使用IgnoreNotFind,但它无法帮助我克服上述错误
如果我错过了一篇关于这个问题解决方案的帖子,请将我链接到它,否则欢迎思考如何前进。也许有一个更直接的途径,我将不得不努力实现我的目标,获得一个好的类别列表,但我不太熟悉的框架,知道下一步是什么。请注意,我无法对这些表中的任何一个进行写入
谢谢,里奇
我的模型的简化版本:
工单对象:
class JobOrder {
def getJobCategories() {
def cats = []
try {
def jocategories = this.categories
if(!jocategories.isEmpty() && jocategories!=null){
println "we got categories for ${this.id}"
jocategories.each { cat ->
if(cat?.parentCategoryID == 0){
if(cat.occupation != null){
cats << cat.occupation
} else {
cats << cat.name
}
}
}
}
} catch(e) {
cats << "Other Area(s)"
}
cats
}
static mapping = {
table 'dbo.JOBORDER'
version false
id generator: 'identity', column: 'JOBORDERID'
/*
* several other mapped columns deleted here
*/
categories joinTable:[name:'jobOrderCategories', column: 'categoryId', key:'jobOrderID']
}
/*
* several properties deleted here
*/
static hasMany = [categories: Category] //several other hasMany associations exist
}
class Category {
static mapping = {
table 'CATEGORY'
version false
id generator: 'identity', column: 'categoryID'
occupation column: 'OCCUPATION'
name column: 'NAME'
parentCategoryID column: 'PARENTCATEGORYID'
/*
* several other mapped columns deleted here
*/
jobOrders joinTable:[name:'jobOrderCategories', column: 'jobOrderID', key:'categoryId']
}
String name
String occupation
int parentCategoryID
/*
* several properties deleted here
*/
static belongsTo = [JobOrder]
static hasMany = [jobOrders:JobOrder]
}
class JobOrderCategories {
static mapping = {
table 'JOBORDERCATEGORIES'
version false
isDeleted column: 'ISDELETED'
jobOrderID column: 'JOBORDERID'
categoryId column: 'CATEGORYID'
}
Boolean isDeleted
Integer jobOrderID
Integer categoryId
}
联接表:
class JobOrder {
def getJobCategories() {
def cats = []
try {
def jocategories = this.categories
if(!jocategories.isEmpty() && jocategories!=null){
println "we got categories for ${this.id}"
jocategories.each { cat ->
if(cat?.parentCategoryID == 0){
if(cat.occupation != null){
cats << cat.occupation
} else {
cats << cat.name
}
}
}
}
} catch(e) {
cats << "Other Area(s)"
}
cats
}
static mapping = {
table 'dbo.JOBORDER'
version false
id generator: 'identity', column: 'JOBORDERID'
/*
* several other mapped columns deleted here
*/
categories joinTable:[name:'jobOrderCategories', column: 'categoryId', key:'jobOrderID']
}
/*
* several properties deleted here
*/
static hasMany = [categories: Category] //several other hasMany associations exist
}
class Category {
static mapping = {
table 'CATEGORY'
version false
id generator: 'identity', column: 'categoryID'
occupation column: 'OCCUPATION'
name column: 'NAME'
parentCategoryID column: 'PARENTCATEGORYID'
/*
* several other mapped columns deleted here
*/
jobOrders joinTable:[name:'jobOrderCategories', column: 'jobOrderID', key:'categoryId']
}
String name
String occupation
int parentCategoryID
/*
* several properties deleted here
*/
static belongsTo = [JobOrder]
static hasMany = [jobOrders:JobOrder]
}
class JobOrderCategories {
static mapping = {
table 'JOBORDERCATEGORIES'
version false
isDeleted column: 'ISDELETED'
jobOrderID column: 'JOBORDERID'
categoryId column: 'CATEGORYID'
}
Boolean isDeleted
Integer jobOrderID
Integer categoryId
}
这类情况并不是最有趣的,但我以前不得不处理这类Roll Your Own ORM问题;)基本上,您在这里要做的是将对象属性存储为int,而不是作为对象引用,虽然您会丢失一些GORM制作的动态查找程序,但您将有一个相当直接的方法来访问数据,而不涉及将自己与Hibernate的内部纠缠在一起 基本上,这将涉及放弃您的hasMany和belongsTo作业订单和类别上的属性。相反,你会想做一些事情,比如
def myJobOrder = JobOrder.get(yourId);
def myCategoryIds = JobOrderCategories.findAllByJobOrderID(myJobOrder.id)
def myCategories = Categories.withCriteria {
in('id', myCategoryIds)
}
您可以将这些遍历的变体放在类的helper方法中,例如,您的getJobCategories方法可以成为
class JobOrder {
//...
def getJobCategories() {
def myCategoryIds = JobOrderCategories.findAllByJobOrderID(this.id)
def myCategories = Categories.withCriteria {
in('id', myCategoryIds)
}
}
}
等等。这绝对不是世界上最漂亮的事情,你失去了用GORM轻松穿越事物的能力
成为执行任务类型的情况。)
但总的来说,这还不算太糟糕:)
希望有帮助 您不能写入任何表,因为您没有直接的DB写访问权限?你的应用没有DB写访问权限?你有更新/删除权限吗?因为这确实是一个数据完整性问题,这就是解决方案。因此,如果你必须解决这个问题,很可能会出现一些问题,你可能需要对ORM进行一些分解,才能找到你需要的地方(如果确实有必要,我很乐意提供帮助,我以前也做过,但这并不是最有趣的事情:/)我访问的数据是只读的,因为它是从供应商的数据库同步的(数据所有者的)场外系统。我们可以在内部将其用作本地数据存储,而不对其数据进行任何更改。更改数据会破坏其单向同步,然后我们必须支付美元,让他们将我们的存储硬重设回其外部数据。这就是我无法写入的意思。;)我现在正在努力制作一个工作指令处理程序,它能让我们从冬眠状态中恢复过来,并在这一次咳血。使用没有RI的数据真的很糟糕。是的,有限的数据访问和第三方集成确实有点糟糕:)不过我现在还不想在hibernate上进行隔离。我会写一个更正式的答案,但基本上最简单的方法是将ID存储为INT,而不是用GORM映射它们。马上给你回电话!这其实并不可怕,我不得不在其他语言/框架环境中做得更糟。让我来总结一下,并运行一些测试!谢谢。我想观点是相对的;)我的职业生涯基本上完全是从grails开始的,这让事情变得不那么美好。不过,与Java/Spring/Hibernate中的一些黑客相比,我完全相信相比之下,它看起来非常干净;)如果事情不顺利,需要进一步调查,请告诉我!非常好,使用上面的概念似乎很好。作为总结:1)删除了belongsTo/hasMany关系2)向jobOrderCategory模型添加了复合键3)更新了getJobCategories以检索具有findAllByJobOrderID的jobOrderCategories集合4)从JobOrderCategority集合中获取了具有条件的类别集合。非常感谢!