"Динамическая" структура проверки Java? - PullRequest
3 голосов
/ 19 мая 2010

AFAIK JSR-303 - стандартная система проверки бинов.

Я не знаю, может ли он выполнить такие проверки (наверное, нет):

  • если объект имеет установленный флаг удаления, вы не можете изменить объект
  • вы не можете изменить свойство даты начала, после того, как дата пройдена
  • вы не можете уменьшить некоторые целочисленные свойства в bean-компоненте

Так, как я могу обработать проверки, которые зависят от предыдущего состояния объекта?

Я бы хотел решить подобные проблемы в среде hibernate3.5 - spring3 - JPA2.

Спасибо


Мое решение состояло в том, чтобы связываться с hibernate, перезагрузить объект, чтобы увидеть старое состояние (после удаления нового объекта). На этот раз мне нужно более разумное решение ...

Ответы [ 7 ]

2 голосов
/ 19 мая 2010

Я не думаю, что это можно сделать с помощью валидации JSR 303 (или любой другой инфраструктуры валидации, которую я использовал). Валидация обычно выполняется без сохранения состояния - вы передаете ему экземпляр объекта, и ваша инфраструктура валидации проверяет, чтобы убедиться, что текущие значения вашего объекта действительны. Нет реального знания о предыдущих состояниях объекта.

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

1 голос
/ 28 мая 2010

Похоже, что поля, которые вы хотите проверить (относительно предыдущего состояния), представляют собой все метаданные о записях, а не реальные данные. Все эти поля (idDeleted, madeDate и т. Д.) Лучше оставить вне уровня вашего домена и поэтому не требуют проверки. Я бы поставил логику для определения и установки этих значений на вашем уровне доступа к данным, чтобы системы, использующие ваши интерфейсы репозитория, не должны знать или заботиться о том, чтобы получить их правильно.

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

Надеюсь, вы найдете разумное решение.

0 голосов
/ 06 августа 2010

Возможно, вы захотите взглянуть на OVal . Мы проводим такую ​​проверку постоянно. Обычно это делается с помощью SimpleCheck, где вы получаете объект и значение и можете выполнять все виды перекрестной проверки.

0 голосов
/ 28 мая 2010

Совершенно другой подход состоит в том, чтобы поместить проверочные проверки в установщики свойств. Недостатком является то, что вы потеряете декларативность.

Пример:

public void setCounter(int newCounter) {
    if (newCounter < this.counter) {
       throw new IllegalOperationException("Cannot decrease the counter");
    } else {
       this.counter = newCounter;
    }
}
0 голосов
/ 28 мая 2010

Я не знаю ни одного готового к использованию решения.Как вы подозреваете, JSR-303 не будет выполнять эту работу, потому что его проверка является «статической».

Но ...

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

если для объекта установлен удаленный флаг, вы не можете изменить объект

Этот вариант я бы реализовал как проксиметод зарегистрирован вокруг каждого сеттера.Прокси-метод будет проверять флаг «удален».Если для него задано значение true, будет сгенерировано исключение, в противном случае будет выполнен исходный метод.

Вы не можете изменить свойство даты начала, после того как дата пройдена

Этот похож.На этот раз у вас не будет доступа ни к какому другому свойству перехваченного установщика, но к исходному (пока не измененному) значению поля и аргумента установщика.боб

Это то же самое, что и с датами, единственная разница - тип даты (дата против целого числа).

Можно утверждать, что AOP являетсяхороший выбор для этой задачи, но все же решение.Я тоже сомневаюсь.

Еще одна проблема заключается в том, что, я думаю, вы захотите применить эти ограничения к сущностям JPA.Таким образом, использование Spring AOP будет не таким простым, поскольку сущности не будут управляться Spring.

0 голосов
/ 22 мая 2010

Я бы, вероятно, создал бы временное поле, которое говорит предыдущую версию, которая указывает на копию данных, которая представляет его предыдущее состояние. Этот объект создается при создании, но поскольку он помечен как временный, он не сериализуется. Затем сделайте проверку против этого.

Простейшей реализацией было бы добавить метод makeACopy (), который создает копию объекта и помещает его в поле.

Вы можете добавить сложность, реализовав Clonable или создав служебный класс, который будет отражать, но это зависит от вас. Я предлагаю makeACopy () и рефакторинг позже, так как об этом легче думать.

0 голосов
/ 19 мая 2010

как я могу обработать проверки, которые зависят от предыдущего состояния объекта?

Я не уверен на 100%, что это выполнимо, но я могу думать только о том, чтобы создать граф объектов, состоящий из "нового состояния" и "старого состояния" (переходный процесс), и проверить граф объекта в целом, используя пользовательские ограничения. По крайней мере, я бы попробовал.

...