VoyageMongo: нормально ли переопределять # = в постоянных классах? - PullRequest
0 голосов
/ 08 января 2019

У меня проблема с VoyageMongo. Я получаю дублированные объекты, когда редактирую их (т.е. изменяю и сохраняю уже сохраненные объекты), особенно те, которые переопределяют #= и #hash.

Вот (упрощенный) случай: у меня есть класс UserAccount, с экземплярами vars email, salt (для шифрования пароля) и name. Это методы #= и #hash:

= anObject
    (self isKindOf: anObject class)
        ifFalse: [ ^ false ].
    ^ self email = anObject email and: [ self salt = anObject salt ]

hash
    ^ (self salt hash + self email hash) hash

email и salt устанавливаются при создании и никогда не изменяются. Вот небольшой сценарий:

UserAccount removeAll.
20 timesRepeat: [ UserAccount new save ].
10 timesRepeat: [ UserAccount selectAll atRandom
            name: 'Joe Doe';
            save ].
UserAccount selectAll size = 20

Это генерирует 20 UserAccount с (#new создает экземпляр со случайной электронной почтой и солью в этом случае), затем выбирает 10 случайным образом и редактирует их имена. Окончательный размер UserAccount selectAll должен оставаться на уровне 20, но обычно он больше , что означает, что он хранит дубликаты.

Возможный виновник: отладка в VOCache, WeakKeyDictionary, содержащая кэшированные объекты (в reversedObjects var, где сами объекты являются ключами), иногда не удается "поразить" существующий объект, поскольку #scanFor: начинает смотреть на разные точки (точнее, #startIndexFor:) по мере увеличения массива ключей. Когда это происходит, я вижу объект внутри VOCache reversedObjects, но VOCache>>keyAtValue: не может его найти.

Короче говоря:

  • разве я не должен переопределять #= в постоянных объектах? Или ...
  • разве мой #hash не реализован?

Или, конечно, любой другой вопрос, который я не вижу :) 1050 *

Большое спасибо!

PS: протестировал это в Pharo 6.1 и 7 с последней версией VoyageMongo.

1 Ответ

0 голосов
/ 14 января 2019

Как правило, вы не должны переопределять # = и #hash в объектах сущности, поскольку они должны основываться на идентичности и значении.

Если 2 объекта совпадают по значениям своих параметров, это не обязательно означает, что они представляют одну и ту же сущность; если вам действительно нужно переопределить # =, тогда вам понадобится бизнес-ключ . Лучше всего просто не переопределять и просто использовать объекты сущностей, основанные на идентичности, когда вы извлекаете их из БД. то есть, как будто вы работаете с OO DB.

Возможно, это ошибка Voyage, поскольку переменная reversedObjects должна быть WeakIdentityKeyDictionary?

...