Функция Kotlin copy () создает новый идентификатор для объекта JPA, в результате чего создается новая строка - PullRequest
0 голосов
/ 21 октября 2018

У меня есть метод обновления на контроллере пружины, который принимает запрос и использует copy для копирования содержимого в загруженную сущность.Как только функция copy () вызывается, свойство id объекта изменяется на новое.

@PutMapping("/{id}")
    fun update(@PathVariable id: UUID, @RequestBody request: UpdateSocietyRequest): ResponseEntity<SocietyUpdatedResponse> {
        val society = societyRepository.findById(id).orElse(null) ?: return notFound().build()
        val updatedSociety = society.copy(
                name = request.name,
                phone = request.phone,
                address = Address(
                        request.addressLine1,
                        request.addressLine2,
                        request.addressLine3,
                        request.city,
                        request.state,
                        request.zipCode
                )
        )
        societyRepository.save(updatedSociety)
        return ok(SocietyUpdatedResponse(updatedSociety.id, updatedSociety.name, updatedSociety.phone))
    }

Entity.kt

@MappedSuperclass
@JsonIgnoreProperties(value = ["createdOn, updatedOn"], allowGetters = true)
@EntityListeners(AuditingEntityListener::class)
abstract class BaseEntity {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    val id: UUID = UUID.randomUUID()

    @Column(nullable = false, updatable = false)
    @CreatedDate
    var createdOn: LocalDateTime = LocalDateTime.now()

    @Column(nullable = true)
    @LastModifiedDate
    var updatedOn: LocalDateTime? = null

    @Column(nullable = false, updatable = false)
    @CreatedBy
    var createdBy: String? = null

    @Column(nullable = true)
    @LastModifiedBy
    var updatedBy: String? = null
}

@Embeddable
data class Address(val addressLine1: String,
                   val addressLine2: String,
                   val addressLine3: String,
                   val city: String,
                   val state: String,
                   val zipCode: Int)

@Entity
data class Society(
        @NotNull
        val name: String,

        @NotNull
        val phone: String,

        @Embedded
        val address: Address
) : BaseEntity()

Насколько я знаю, копия не должна создавать новый объект, а меняет существующий с новым значением из запроса.Почему id назначается новый UUID?

Спасибо

1 Ответ

0 голосов
/ 22 октября 2018

Согласно эта ссылка только свойства, определенные в скобках, будут использоваться в функции copy (), тогда id и другие свойства, унаследованные от суперкласса, не будут использоваться.Я протестировал его.

Свойства, объявленные в теле класса

Обратите внимание, что компилятор использует только свойства, определенные внутри основного конструктора, для автоматически сгенерированных функций.Чтобы исключить свойство из сгенерированных реализаций, объявите его внутри тела класса:

класс данных Person (имя val: String) {var age: Int = 0}

Будет только имя свойстваиспользоваться внутри реализаций toString (), equals (), hashCode () и copy (), и будет только одна компонентная функция component1 ().Хотя два объекта Person могут иметь разный возраст, они будут рассматриваться как равные.

Однако мое решение:

Не используйте функцию copy().Просто измените свойства society и сохраните его.Вы можете изменить свойства val, но вы не можете изменить ссылку (society = something запрещено).

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

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

@Entity
data class Society(
        @NotNull
        var name: String,

        @NotNull
        var phone: String,

        @Embedded
        var address: Address
) : BaseEntity()

...

@PutMapping("/{id}")
    fun update(@PathVariable id: UUID, @RequestBody request: UpdateSocietyRequest): ResponseEntity<SocietyUpdatedResponse> {
        val society = societyRepository.findById(id).orElse(null) ?: return notFound().build()
        society.name = request.name
        society.phone = request.phone
        society.address = Address(
                        request.addressLine1,
                        request.addressLine2,
                        request.addressLine3,
                        request.city,
                        request.state,
                        request.zipCode
                )
        )
        societyRepository.save(society)
        return ok(SocietyUpdatedResponse(society.id, society.name, society.phone))
    }

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

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