2015-11-05 2 views
0

Я работаю над приложением, использующим Grails 2.4.5 и Hibernate 3.6.10. Существует объект домена, у которого есть дочерний PersistentMap. На этой карте хранятся пары ключей-значений 4 , где значение всегда является строкой.Hibernate PersistentMap возвращает неправильные значения

В наших тестовых средах все работает нормально, а затем иногда постоянная карта начинает возвращать «1» для ключа или значения. Другие значения в родительском доменном объекте прекрасны. Проблема была решена, когда она возникает путем обновления одной из записей для карты непосредственно в базе данных. Это заставляет меня думать о какой-то проблеме кеширования, , но я не смог ее воссоздать в локальной среде.

База данных под MySQL.

Следующий код не является фактическим, но представляет структуру.

class MyDomain { 

    static belongsTo = [owner: Owner] 

    static hasMany = [relatedDomains: RelatedDomain] 

    Set relatedDomains = [] 

    Map flags = [:] 

    String simpleItem 

    String anotherItem 

    static constraints = { 
     owner(nullable: true) 
     relatedDomains(nullable: true) 
     flags(nullable: true) 
     simpleItem(nullable: true) 
     anotherItem(nullable: true) 
    } 
} 

Это приводит несколько таблиц (без учета RelatedDomain и владельца):

mydomain table 
| id | version |owner_id|simple_item|another_item | 
|-------|-----------|--------|-----------|-------------| 
| 1 | 1  | 1 | A value |Another value| 

mydomain_flags table 

|flags| flags_ids | flags_elt | 
|-----|-----------|-------------| 
| 1 | KEY_ONE | VALUE_ONE | 
| 1 | KEY_TWO | VALUE_TWO | 
| 1 | KEY_THREE | VALUE_THREE | 

Когда экземпляр MyDomain извлекается карта флаги будут иметь:

[ "KEY_ONE": "VALUE_ONE", "KEY_TWO": "VALUE_TWO", "KEY_THREE" :"VALUE_THREE"] 

Иногда карте содержит:

[ "KEY_ONE": "1", "KEY_TWO": "1", "KEY_THREE" :"1"]<br/> 

ИЛИ

[ "1": "VALUE_ONE", "1": "VALUE_TWO", "1" :"VALUE_THREE"] 

Остальная часть данных в экземпляре MYDOMAIN является правильным. Кажется, что это только карта флагов. Приложение только считывает информацию для mydomain и flags, оно никогда не обновляет данные. Это в основном данные конфигурации для приложения.

Неужели кто-нибудь еще видел подобное поведение? Я не знаю, связано ли это с гибернацией (версия 3.6.10) или с Grails/Gorm или с обоими. Я не смог воспроизвести его локально, но это произошло в двух отдельных средах.

ответ

0

Я отследил его до проблемы с спящим режимом. Алиасы, созданные для постоянной карты, привели к тому же псевдониму для ключа и элемента. Это связано с тем, что псевдонимы основаны на статическом счетчике в классе org.hibernate.mapping.Table (в 3.6.10). Причина, по которой она была спорадической, заключалась в том, что Grails загружает все классы домена в HashSet и затем выполняет итерации по набору, связывающему каждый. Так как Set неупорядочен, иногда класс домена с постоянной картой будет отображен 3-м классом, что приведет к ключевому псевдониму, идентичному псевдониму элемента.

Эта проблема была решена в спящем версии 4.1.7 https://hibernate.atlassian.net/browse/HHH-7545

Чтобы обойти эту проблему в Grails, я подклассы класс GrailsAnnotationConfiguration и в конструкторе, создана и отбрасываются 10 Hibernate экземпляров таблицы. Это увеличило статический счетчик до более безопасного начального значения перед загрузкой классов домена Grails.

Смежные вопросы