Подтвердить что ты не робот

Spring Данные JPA - Почему изменения в возвращаемом объекте автоматически сохраняются?

Я представляю вопрос на примере.

Убедитесь, что у нас есть репозиторий, например, ниже:

public interface ExampleObjectRepository extends CrudRepository<ExampleObject, Long> {

}

Расширяя интерфейс JpaRepository, репозиторий ExampleObject наследует следующий метод:

T findOne(ID id);

Теперь я заметил, что если я получаю ссылку на объект ExampleObject после вызова этого метода, любые манипуляции, которые я делаю с этим методом, автоматически сохраняются в базе данных, например:

ExampleObject pointInCase = exampleObjectRepository.findOne(1L);
pointInCase.setName("Something else");

Прочитав тему, я понимаю, что это означает, что ExampleObject экземпляр not detached.

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

T save(T entity);

Может ли кто-нибудь быть достаточно любезен, чтобы подтвердить, что объекты, возвращенные из репозитория данных JPA Spring, остаются прикрепленными в качестве стандарта и объясняют, как использовать API для отметки метода в репозитории, так что он возвращает только отобранные ссылки?

Я предполагаю, что изменение состояния объекта также может изменить его определение, когда оно используется с указанным методом save(T entity), поэтому я также хотел бы понять, как обрабатывается идентификация для обновлений.

4b9b3361

Ответ 1

Это фундаментальный принцип JPA. Вы работаете с прикрепленными (управляемыми) объектами, и каждая модификация, сделанная на этих управляемых объектах, автоматически становится постоянной.

Если вы не хотите, чтобы ваши изменения были постоянными, не делайте изменений или отката транзакции.

Работа над отдельными объектами была бы кошмаром, потому что это предотвратило бы ленивую загрузку всех ассоциаций. Вы всегда можете называть EntityManager.detach() на своих сущностях, но я действительно этого не делал. Просто попробуйте понять, как это работает и с чем это связано. Есть гораздо больше преимуществ, чем недостатков. Один из них заключается в том, что вам даже не нужно думать о сохранении всех изменений, которые может сделать сложная бизнес-логика, поскольку все это сделано для вас JPA, прозрачно.

Ответ 2

Вы можете сделать свои репозитории возвращенными сущностями, если ваша транзакция привязана к репозиторию. То есть ваша транзакция начинается с входа в репозиторий и закрывается, когда вы выходите из репозитория.

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

Для модификаций я использую другую область транзакций, которая завершает полный процесс загрузки, меняя (и неявно сохраняя).