Spring boot 函数的作用是:在JPA实体上创建一个新Id,从而生成一个新行

Spring boot 函数的作用是:在JPA实体上创建一个新Id,从而生成一个新行,spring-boot,kotlin,spring-data-jpa,Spring Boot,Kotlin,Spring Data Jpa,我在spring控制器上有一个更新方法,它接收请求并使用copy将内容复制到加载的实体中。一旦调用copy(),实体上的id属性就会更改为新属性 @PutMapping("/{id}") fun update(@PathVariable id: UUID, @RequestBody request: UpdateSocietyRequest): ResponseEntity<SocietyUpdatedResponse> { val society = soc

我在spring控制器上有一个更新方法,它接收请求并使用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))
    }
据我所知,copy不应该创建新对象,而是使用请求中的新值更改现有对象。为什么要为id分配新的UUID

谢谢

根据copy()函数中仅使用括号之间定义的属性,则不会使用从超类继承的id和其他属性。我测试过了

在类主体中声明的属性

请注意,编译器仅使用 在主构造函数中为 自动生成的函数。将属性从列表中排除的步骤 生成的实现,在类主体中声明它:

数据类Person(val name:String){var age:Int=0}

在toString()、equals()、hashCode()和copy()实现中仅使用属性名,以及 只有一个组件函数component1()。两岁 个人对象可以有不同的年龄,他们将被视为平等的

然而,我的解决办法是:

不要使用
copy()
功能。只需更改
社会
的属性并保存即可。您可以更改
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))
    }
@实体
数据阶级协会(
@NotNull
变量名称:String,
@NotNull
电话:字符串,
@嵌入
变量地址:地址
):BaseEntity()
...
@PutMapping(“/{id}”)
有趣的更新(@PathVariable id:UUID,@RequestBody请求:UpdateSocietyRequest):ResponseEntity{
val society=societyRepository.findById(id).orElse(null)?:return notFound().build()
society.name=request.name
society.phone=request.phone
地址(
request.addressLine1,
request.addressLine2,
request.addressLine3,
请求,城市,
请说明,
request.zipCode
)
)
societyRepository.save(社会)
返回ok(SocietyUpdatedResponse(society.id、society.name、society.phone))
}

此外,我认为在数据类中使用继承可能会造成混淆,因此最好避免使用继承。

copy()顾名思义,创建对象的副本。如果它改变了原始对象,它的VAL会改变,而VAL不能改变。是的,所以updatedSociety是从存储库加载的society对象的副本,并使用副本中的值进行更新……为什么updatedSociety上会有新的UUID?因为唯一复制的属性是在数据类的主构造函数中声明的属性
id
是一个val,由超类用
new UUID()
初始化。而且val也不可能被重新分配。因此,除了
new UUID()
之外,它不可能有任何其他值。此外,文档中还提到:请注意,编译器只使用主构造函数中为自动生成的函数定义的属性。。其他注意事项:为什么您自己分配UUID,并且还指定UUID应该由JPA生成?感谢Mostafa,如果我将属性更改为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))
    }