Как избежать NHibernate. NonUniqueObjectException

кроме того, действительно ли они уникальны для Java, есть ли эквивалентный C++?

нет, но VB и C# имеют атрибуты , которые являются тем же самым.

Их использование довольно разнообразно. Один типичный пример Java, @Override не имеет никакого эффекта на код, но это может использоваться компилятором для генерации предупреждения (или ошибка), если украшенный метод на самом деле не переопределяет другой метод. Точно так же методы могут быть отмечены устаревшие.

Тогда существует отражение. При отражении типа класса в коде можно получить доступ к атрибутам и действию согласно информации, найденной там. Я не знаю примеров в Java, но в.NET, которую это используется компилятором, чтобы генерировать (de) сериализация информация для классов, определить , расположение памяти из структур и объявляет функциональный импорт из библиотек прежней версии (среди других). Они также управляют, как конструктор форм IDE работает.

РЕДАКТИРОВАНИЕ/: Атрибуты на классах сопоставимы для меток интерфейсов (как сериализуемый в Java). Однако в инструкциях по кодированию.NET говорится для не использования интерфейсов тега. Кроме того, они только работают на уровне класса, не на уровне метода.

8
задан Jason Barile 11 November 2009 в 05:13
поделиться

2 ответа

Поскольку TagName является идентификатором, вы работаете с картой идентификации NHibernate. Его карта идентичности уже знает об объекте с тем же идентификатором, поэтому выдает это исключение.

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

Пример псевдокода:

var tag = session.Get<Tag>("Tag 1");

if (tag != null)
{
   post.AddTag(tag);
}
else
{
   post.AddTag(new Tag("Tag 1"));
}

Это сообщение в блоге даст вам подробное объяснение: NHibernate - Межсессионные операции

8
ответ дан 5 December 2019 в 14:03
поделиться

То, как вы это делаете, не то, как я бы сделал, но вот как решить вашу проблему. Обычно в объектно-ориентированном программировании следующие 2 объекта НЕ равны:

var object1 = new Tag("hello");
var object2 = new Tag("hello");

var areSame = (object1 == object2); // false

Вы создали 2 отдельных объекта с одинаковым состоянием, но это два разных объекта, поэтому, если вы сравните их на равенство, они не будут одинаковыми. Очевидно, что когда дело доходит до NHibernate, эти объекты на самом деле являются одним и тем же объектом.

Мы решаем эту проблему для NHibernate, переопределив 2 метода класса объектов. GetHashCode () и Equals ()

GetHashCode () в основном возвращает уникальный хэш-код, основанный на состоянии объекта. Equals () сравнивает два объекта на равенство

следующим образом:

public override int GetHashCode()
{
    return (this.GetType() + "|" + _tagName).GetHashCode();
}

public override bool Equals(object obj)
{
    return this.GetHashCode() == obj.GetHashCode();
}

Обычно GetHashCode объединяет тип объекта и имя тега в виде строки, т.е. App.Domain.Tag | nameoftag и генерирует хэш-код для этой строки

Equals (), затем сравнивает результат GetHashCode () для первого объекта с результатом GetHashCode () для второго объекта, чтобы проверить равенство. Если вы сделаете это с двумя объектами, которые мы определили выше, два хэш-кода будут одинаковыми, и поэтому сравнение для Equals () будет истинным. Когда NHibernate проверяет два объекта на равенство во внутренней работе, он определит, что они одинаковы, и должен решить вашу проблему.

4
ответ дан 5 December 2019 в 14:03
поделиться
Другие вопросы по тегам:

Похожие вопросы: