Неизменяемые объекты Kotlin неожиданно меняются при использовании его с JPA - PullRequest
0 голосов
/ 07 января 2019

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

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

val instance1 = repository.findById(entityId)
repository.save(instance1.copy(deletedAt = Instant.now()))
..
..
assertNull(instance1.deletedAt())

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

Кажется, существует конфликт между контекстом сохраняемости JPA (кеш первого уровня) и логикой неизменяемого и копируемого метода Котлина.

Кто-нибудь сталкивается с этой проблемой или любым предложением или лучшими методами при использовании JPA и неизменных сущностей Kotlin?

1 Ответ

0 голосов
/ 07 января 2019

Я подозреваю, что проблема в том, что вы игнорируете возвращаемое значение из save(). Его документы говорят:

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

Но вы этого не делаете; вместо этого вы продолжаете использовать исходный экземпляр, который (как говорится) мог измениться.

Вместо этого сохраните возвращаемое значение из save() и используйте его после этого. (Либо сделав instance1 a var, либо создав новый val и не ссылаясь на instance1 впоследствии.)

(Это не специфичная для Kotlin проблема, и она точно такая же в Java. JPA, Spring и т. Д. Делают свое дело, используя байт-код, поэтому могут делать то, что не может сделать ваш код, например, изменять неизменяемый значения. Большую часть времени вы можете игнорировать это, но этот случай делает это очевидным.)

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...