Каковы различия между различными методами сохранения в, в спящем режиме?

Каждый раз, когда кто-то использует инициализацию двойной скобки, котенка убивают.

Помимо синтаксиса, довольно необычного и не очень идиоматического (вкус, конечно, дискуссионный), вам необязательно создавать две существенные проблемы в вашем приложении , о котором я только что недавно подробно рассказал здесь .

1. Вы создаете слишком много анонимных классов

Каждый раз, когда вы используете инициализацию двойной скобки, создается новый класс. Например. этот пример:

Map source = new HashMap(){{
    put("firstName", "John");
    put("lastName", "Smith");
    put("organizations", new HashMap(){{
        put("0", new HashMap(){{
            put("id", "1234");
        }});
        put("abc", new HashMap(){{
            put("id", "5678");
        }});
    }});
}};

... будет генерировать эти классы:

Test$1$1$1.class
Test$1$1$2.class
Test$1$1.class
Test$1.class
Test.class

Это довольно немного накладных расходов для вашего загрузчика классов - ни за что! Конечно, это не займет много времени для инициализации, если вы это сделаете один раз. Но если вы делаете это 20 000 раз по всему вашему корпоративному приложению ... все, что куча памяти только для немного «синтаксиса сахара»?

2. Вы потенциально создаете утечку памяти!

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

public class ReallyHeavyObject {

    // Just to illustrate...
    private int[] tonsOfValues;
    private Resource[] tonsOfResources;

    // This method almost does nothing
    public Map quickHarmlessMethod() {
        Map source = new HashMap(){{
            put("firstName", "John");
            put("lastName", "Smith");
            put("organizations", new HashMap(){{
                put("0", new HashMap(){{
                    put("id", "1234");
                }});
                put("abc", new HashMap(){{
                    put("id", "5678");
                }});
            }});
        }};

        return source;
    }
}

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

Memory Leak Right Here [/g5]

Изображение из http://blog.jooq.org/2014/12/ 08 / dont-be-clever-the-double-curly-braces-anti-pattern /

3. Вы можете притворяться, что Java имеет литералы на карте

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

String[] array = { "John", "Doe" };
Map map = new HashMap() {{ put("John", "Doe"); }};

Некоторые люди могут найти это синтаксически стимулирующее.

197
задан shA.t 1 August 2018 в 00:02
поделиться

3 ответа

Вот мое понимание методов. Главным образом они основаны API хотя, поскольку я не использую все их на практике.

Вызовы saveOrUpdate или сохраняют или обновляют в зависимости от некоторых проверок. Например, если никакой идентификатор не существует, сохранение называют. Иначе обновление называют.

сохраняют , Сохраняет объект. Присвоит идентификатор, если Вы не будете существовать. Если Вы делаете, это по существу делает обновление. Возвращает сгенерированный идентификатор объекта.

обновление Попытки сохранить объект с помощью существующего идентификатора. Если никакой идентификатор не существует, я полагаю, что исключение выдается.

saveOrUpdateCopy Это удерживается от использования и больше не должно использоваться. Вместо этого существует...

слияние Теперь это - то, где мое знание начинает колебаться. Важной вещью здесь является различие между переходным процессом, отсоединенным и персистентными объектами. Для большего количества информации об объектных состояниях, смотрят здесь . С сохранением & обновление, Вы имеете дело с постоянными объектами. Они связаны с Сессией, так Будьте в спящем режиме, знает то, что изменилось. Но когда у Вас есть временный объект, нет никакой включенной сессии. В этих случаях необходимо использовать слияние для обновлений и сохраниться для сохранения.

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

117
ответ дан Lee Theobald 23 November 2019 в 05:15
поделиться
  • Видят эти , в спящем режиме, Форум для объяснения тонких различий между сохраняет и сохраняет. Похоже, что различием является время, оператор INSERT в конечном счете выполняется. С тех пор сохраняют , действительно возвращает идентификатор, оператор INSERT должен быть выполнен немедленно независимо от состояния транзакции (который обычно является плохой вещью). Сохраняются , не выполнит операторов за пределами в настоящее время рабочей транзакции только для присвоения идентификатора. Сохраните/Сохраните обе работы над переходные экземпляры , т.е. экземпляры, которые еще не имеют никакого идентификатора, присвоенного и как такового, не сохраняются в DB.

  • Обновление и Слияние обе работы над отдельные экземпляры , т.е. экземпляры, которые имеют соответствующую запись в DB, но которые в настоящее время не присоединяются к (или управляются), Сессия. Различие между ними - то, что происходит с экземпляром, который передается функции. обновление попытки повторно прикрепить экземпляр, который означает, что не может быть никакого другого экземпляра персистентного объекта, присоединенного к Сессии прямо сейчас иначе, исключение выдается. слияние , однако, просто копии все значения к персистентному экземпляру на Сессии (который будет загружен, если это не будет в настоящее время загружаться). Входной объект не изменяется. Так слияние является более общим, чем [1 114] обновление , но может использовать больше ресурсов.

66
ответ дан Eugen Labun 23 November 2019 в 05:15
поделиться

Знайте, что при вызове обновления на отделенном объекте всегда будет обновление, сделанное в базе данных, изменили ли Вы объект или нет. Если это не то, что Вы хотите Вас, должен использовать Session.lock () с LockMode. Ни один.

необходимо назвать обновление, только если объект был изменен вне объема текущей сессии (когда в отдельном режиме).

2
ответ дан bernardn 23 November 2019 в 05:15
поделиться
Другие вопросы по тегам:

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