Это хорошая практика для инициализации полей внутри объекта получения JPA? - PullRequest
15 голосов
/ 17 октября 2011

В Java-бобах POJO такой код может быть полезен, особенно для коллекций:

class POJO {
    private Collection<X> col;

    public Collection<X> getCol() {
        if (col == null)
           col = new SomeCollection<X>();

        return col;
    }
}

Это позволяет коду, использующему POJO, вызывать pojo.getCol().isEmpty() без дополнительной проверки нуля, таким образом делаяОчиститель кода.

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

Ответы [ 4 ]

20 голосов
/ 17 октября 2011

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

class POJO {
    private Collection<X> col  = new SomeCollection<X>();

    public Collection<X> getCol() {
        return col;
    }
}

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

12 голосов
/ 17 октября 2011

Я бы настоятельно не рекомендовал ленивую инициализацию свойств в объекте ORM.

У нас была серьезная проблема при ленивой инициализации свойства сущности с использованием Hibernate, поэтому я настоятельно не рекомендовал бы его. Проблема, которую мы увидели, проявлялась в сохранении, когда мы выдавали поисковый запрос. Это потому, что когда объект был загружен, свойство было пустым, но когда вызывался метод get, он возвращал ленивый инициализированный объект, поэтому hibernate (по праву) считал объект грязным и сохранял его перед выполнением поиска.

2 голосов
/ 17 октября 2011

Как правило, рекомендуется использовать пустые коллекции вместо NULL (для полей, которые являются коллекциями).

Но я не рекомендую то, что вы делаете в геттере.

По моему личному мнению, вышеприведенное "правило" также следует использовать и для внутреннего представления объекта. Таким образом, вы идете лучше с:

class POJO {
    private Collection<X> col  = new SomeCollection<X>();

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

1 голос
/ 17 октября 2011

Ленивая инициализация очень распространена и вполне подойдет.

Есть компромиссы и инициализация в определении конструктора или переменной:

Pro

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

Con

  • Если доступ к полю осуществляется напрямую, вы все равно можете получить нулевой указатель.
  • Установка значения по умолчанию в определении переменной более понятна.
  • Если объект используется одновременно, отложенная инициализация может быть проблемой параллелизма.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...