Хобрук: Ваш путь к мастерству в программировании

Проверить уникальность экземпляра класса домена

У меня есть приложение Grails с кучей доменных классов, некоторые из которых имеют много полей, некоторые из которых имеют отношение hasMany к рассматриваемому доменному классу. Для этого конкретного приложения у меня есть только одно «ограничение», то есть каждый экземпляр каждого доменного класса должен быть уникальным. Меня не волнует, имеет ли произвольное поле одно и то же значение в нескольких экземплярах одного и того же доменного класса, если каждый экземпляр сделан уникальным значением какого-либо другого поля в этом доменном классе. Поэтому в основном я хочу, чтобы проверка происходила на уровне экземпляра класса домена, а не на уровне поля класса домена. Прямо сейчас я делаю это, используя очень классную аннотацию @EqualsAndHashCode для генерации моих методов equals и hashCode, а затем вызывая equals в пользовательском валидаторе для некоторого произвольного поля доменного класса.

Два вопроса:

  1. Есть ли более эффективный способ проверки уникальности класса предметной области?
  2. Если нет, то есть ли способ вызвать свой пользовательский код валидатора в самом экземпляре класса домена вместо того, чтобы проходить через одно из полей экземпляра класса домена?
@groovy.transform.EqualsAndHashCode
class MyDomainClass {
    String some
    int arbitrary
    boolean field
    static constraints = {
        // The field I chose to validate on is irrelivant, I just need to run the validation code **somewhere**
        arbitrary validator: { val, obj ->
            return !MyDomainClass.getAll().contains(obj)
         }
    }
}

Я также должен добавить, что ищу общий (надеюсь, эффективный) способ сделать это. Я понимаю, что вызов getAll() очень неэффективен, и вместо этого вызов некоторого варианта find или выполнение запроса HQL к точным полям каждого доменного класса было бы намного эффективнее... просто написание занимает намного больше времени!

Примеры

    assert MyDomainClass.getAll().isEmpty() // true

    def myDomainClass1 = new MyDomainClass( some: "foo", arbitrary: 1, field: true)
    assert MyDomainClass.getAll().contains(myDomainClass1); // false
    myDomainClass1.save(flush:true)

    def myDomainClass2 = new MyDomainClass( some: "bar", arbitrary: 1, field: true)
    assert MyDomainClass.getAll().contains(myDomainClass2); // false.  Even though this has the same `arbitrary` value as myDomianClass1, it has a different `some` value which makes it unique.
    myDomainClass2.save(flush:true)

    def myDomainClass3 = new MyDomainClass( some: "foo", arbitrary: 1, field: false)
    assert MyDomainClass.getAll().contains(myDomainClass3); // false.  Even though this has the same `some` value as myDomainClass1 and the same `arbitrary` value as myDomainClass1 and myDomainClass2, it has a different `field` value which makes it unique.
    myDomainClass3.save(flush:true)
17.08.2013

  • Трудно понять, что вы спрашиваете. Вы хотите знать, уникален ли доменный класс, но не на уровне поля. Как еще вы могли бы определить, является ли он уникальным, кроме полей домена? Вы не можете сказать arbitrary unique: true ??? В этом случае было бы полезно предоставить фактический пример, с которым вы работаете. 17.08.2013
  • @JamesKleeh Если бы я сказал arbitrary unique: true, это означало бы, что никакое другое поле arbitrary в любом другом экземпляре этого MyDomainClass не может иметь такое же значение. Это не то, чего я хочу. Я хочу, чтобы другой экземпляр MyDomainClass мог иметь точно такое же значение arbitrary, если значения других полей делают экземпляр класса домена уникальным. Я добавлю лучший пример, чтобы проиллюстрировать это. 17.08.2013
  • Итак, вам нужно добавить уникальное ограничение, которое охватывает все поля. some unique: ['arbitrary', 'field'] 17.08.2013
  • @JamesKleh Если бы я использовал несколько столбцов unique (я думаю, это то, что вы предлагаете), мне пришлось бы сделать это для каждого поля в MyDomainClass. Пример: some(unique:['arbitrary', 'field'], затем arbitrary(unique: ['some', 'field']), затем field(unique:['some', 'arbitrary']). Я почти уверен, что это даст мне то, что я хочу (и это определенно более эффективно, чем то, как я это делаю сейчас), но я хотел бы, если возможно, более общее решение. 17.08.2013
  • Вам нужно будет только поставить ограничение на одно поле. Пример, который я показал выше, гарантирует, что некоторое произвольное поле будет уникальным ключом. Все три ваших примера делают одно и то же, какой порядок и какое поле вы помещаете в него... произвольно :) 17.08.2013

Ответы:


1

Это обеспечит уникальность комбинации трех полей в домене. Это также гарантирует, что ограничение находится на уровне базы данных, а не только на уровне приложения.

class MyDomainClass {
    String some
    int arbitrary
    boolean field
    static constraints = {
        some(unique: ['arbitrary', 'field'])
    }
}
17.08.2013
  • Я попробую. Я тестировал это один раз (в прошлом в другом приложении), и я помню, что он работал по-другому. Надеюсь ошибаюсь :) 17.08.2013
  • Похоже, это работает так, как вы думали. Думаю, я сделал это сложнее, чем это было на самом деле :/ 18.08.2013
  • Новые материалы

    Я собираюсь научить вас Python шаг за шагом
    Привет, уважаемый энтузиаст Python! 👋 Готовы погрузиться в мир Python? Сегодня я приготовил для вас кое-что интересное, что сделает ваше путешествие более приятным, чем шарик мороженого в..

    Альтернатива шаблону исходящих сообщений для архитектуры микросервисов
    Познакомьтесь с двухэтапным сообщением В этой статье предлагается альтернативный шаблон для папки Исходящие : двухэтапное сообщение. Он основан не на очереди сообщений, а на..

    React on Rails
    Основное приложение Reverb - это всеми любимый монолит Rails. Он отлично обслуживает наш API и уровень просмотра трафика. По мере роста мы добавляли больше интерактивных элементов..

    Что такое гибкие методологии разработки программного обеспечения
    Что представляют собой гибкие методологии разработки программного обеспечения в 2023 году Agile-методологии разработки программного обеспечения заключаются в следующем: И. Введение A...

    Ториго  — революция в игре Го
    Наш следующий вызов против ИИ и для ИИ. Сможет ли он победить людей в обновленной игре Го? Обратите внимание, что в следующей статье AI означает искусственный интеллект, а Goban  —..

    Простое развертывание моделей с помощью Mlflow — Упаковка классификатора обзоров продуктов NLP от HuggingFace
    Как сохранить свои модели машинного обучения в формате с открытым исходным кодом с помощью MLFlow, чтобы позже получить возможность легкого развертывания. Сегодня модели упаковки имеют несколько..

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