Могу ли я восстановить связь (joinTable) со ссылкой на отсутствующие данные - PullRequest
2 голосов
/ 07 марта 2012

Я прочитал много постов и документов и, должно быть, что-то упустил.

В моем приложении (модель ниже) у меня возникла проблема с данными, которая, по-видимому, вышла из-под контроля, где яcategoryId в объединяемой таблице JOBORDERCATEGORIES, для которой нет соответствующей строки в таблице CATEGORY.Я получаю доступ к данным категории через getJobCategories () в JobOrder.Это приводит к следующей ошибке, когда в моей таблице категорий отсутствует указанная строка:

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]

и мой код останавливается.

Я пытался использовать ignoreNotFound, но это не помогает мне получитьмимо ошибки, указанной выше.

Если я пропустил сообщение о решении этой проблемы, пожалуйста, свяжите меня с ним, в противном случае приветствуются мысли о том, как двигаться дальше.Возможно, есть более прямой путь, который мне придется найти, чтобы достичь своей цели - получить хороший список категорий, но я недостаточно знаком с фреймворком, чтобы знать, что будет дальше.Как примечание, я не могу писать ни в одну из этих таблиц.

спасибо, rich

Упрощенная версия моей модели:

Объект заказа на работу:

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
}

1 Ответ

2 голосов
/ 07 марта 2012

Подобные ситуации не самые веселые, но мне раньше приходилось сталкиваться с подобными проблемами ORM; не типизированные как ссылки на объекты, а как целые, и хотя вы потеряете некоторые из свойств динамического поиска, которые GORM делает такими изящными, у вас будут довольно простые средства доступа к данным, которые не требуют путаницы с Внутренности Спящего.

По сути, это будет связано с отказом от свойств hasMany и ownTo в JobOrder и Category. Вместо этого вы захотите сделать что-то вроде

def myJobOrder = JobOrder.get(yourId);
def myCategoryIds = JobOrderCategories.findAllByJobOrderID(myJobOrder.id)
def myCategories = Categories.withCriteria {
    in('id', myCategoryIds)
}

Вы можете поместить варианты этих обходов в вспомогательные методы для ваших классов, как, например, ваш метод getJobCategories может стать

class JobOrder {
//...
    def getJobCategories() {
        def myCategoryIds = JobOrderCategories.findAllByJobOrderID(this.id)
        def myCategories = Categories.withCriteria {
            in('id', myCategoryIds)
        }
    }
}

И так далее. Это определенно не самая красивая вещь в мире, с которой вам приходится иметь дело, и вы теряете способность легко проходить через GORM (например,

jobOrder.withCriteria {
   categories {
     eq('name', blah)
   }
}

становится ситуацией типа executeQuery.) Но в целом, это не так уж плохо иметь дело с :) Надеюсь, это поможет!

...