Объект значения с OID - PullRequest
       20

Объект значения с OID

2 голосов
/ 31 декабря 2008

Можете ли вы описать плюсы и минусы включения OID (обычно это идентификатор строки базы данных) в POJO , представляющего сущность в вашей модели?

На самом деле я не говорю о проблемах, связанных с equals / hashcode и т. Д., Я должен был бы лучше описать мою проблему (мою плохую :)) ...

У нас есть некоторые из тех классов сущностей, которые представляют бизнес-объекты (например, Product, Catalog и т. Д.). Иногда у них есть «бизнес-идентификатор», например, Product можно найти по его уникальному ProductId (который имеет 3 поля: id, type, repository).

В нашей базе данных таблица Product содержит столбец суррогатного первичного ключа (OID) в дополнение к 3 бизнес-столбцам (id, type, repository), чтобы упростить ссылки на внешние ключи и иметь меньше предложений joins.

Классы Product / ProductId являются частью API, который мы предоставляем другим приложениям. Так, например, они могут позвонить:

productManager.findProductById(ProductId productId);

Вопрос в том, должен ли OID быть включен в Product или в класс ProductId, зная, что от наших клиентов ожидается использование идентификатора ProductId.

Плюсы:

  • Я могу использовать OID для другого поиска, например

    Product p = productManager.findProductById(ProductId productId);
    Catalog c = productManager.findAllCatalogsContainingProduct(p.getOid());
    

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

Минусы:

  • Я только что показал OID клиенту (будем надеяться, что он не использует его вместо бизнес-ключа !!)

Можете ли вы перечислить другие плюсы и минусы?

Ответы [ 2 ]

1 голос
/ 31 декабря 2008

Идентификатор строки базы данных = первичный ключ? Если это так, то у вас нет плюсов или минусов, вы должны их иметь, иначе вы не сможете связать POJO с соответствующей строкой базы данных.

Для извлечения продуктов и каталогов стандартным способом SQL является соединение. Например, с моим DAL я могу сделать:

SearchCriteria sc = new SearchCriteria();
sc.AddBinding("ProductId", productId);
List<Entity> Products = SQL.Read(sc, new Product(new Catalog());

или

List<Entity> Products = SQL.Read(sc, new Catalog(new Product());

Таким образом, нет необходимости сообщать что-либо вызывающему абоненту или о приеме туда и обратно.

0 голосов
/ 31 декабря 2008

Вы можете столкнуться с проблемами, если ваша реализация equals () или hashCode () основана на идентификаторе, так как он, вероятно, сначала будет нулевым, а затем изменится после сохранения объекта. Смотрите ниже:

http://java.sun.com/javase/6/docs/api/java/util/Set.html

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

Предположим, что ваша реализация hashCode () основана на идентификаторе и equals () использует hashCode () для сравнения. Если вы добавите объект в набор и его идентификатор будет равен нулю, сравнение с равными будет выполнено в одну сторону. Если вы затем сохраните объект в наборе, его значение идентификатора, скорее всего, изменится, что приведет к изменению поведения equals () и hashCode (). Это нарушает «контракт» Сета, как описано выше.

Это немного необычный случай, но стоит отметить.

...