使用ID的单向@OneToOne

来源:爱站网时间:2021-09-17编辑:网友分享
我想使用ID创建一个@OneToOne单向关系。让我们考虑以下示例:@Table(name =“ user”)@Entity类User(@Id @GeneratedValue(...)var id:Long?= ...

问题描述


我想使用ID创建@OneToOne单向关系。让我们考虑以下示例:

@Table(name = "user")
@Entity
class User (

    @Id
    @GeneratedValue(...)
    var id: Long? = null,

    @OneToOne
    var address: UserAddress? = null
)

@Table(name = "user_address")
@Entity
class UserAddress(
    @Id
    var id: Long? = null,

    (...)
)

在数据库上,user_address.id上有引用user.id的外键约束。我尝试使用许多不同的注释组合,但是删除仍然存在问题。我正在使用User的JpaRepository,并且当调用userRepository.deleteById(id)时,仅删除了子级(address),而不删除了父级(user)。我真的想保留名称为“ id”的@Id列。可能吗?

编辑

当我使用以下代码时:

@Table(name = "user")
@Entity
class User (

    @Id
    @GeneratedValue(...)
    var id: Long? = null,

    @OneToOne(cascade = [CascadeType.All])
    @JoinColumn(name = "id", referencedColumnName = "id")
    var address: UserAddress? = null
)

@Table(name = "user_address")
@Entity
class UserAddress(
    @Id
    var id: Long? = null,


    @OneToOne(mappedBy = "address")
    var user: User? = null
    (...)
)

[调用userRepository.deleteById(id)时,仅删除子项。我不知道为什么。此外,我想保持这种关系是单向的。

思路一:


您需要的是级联删除,可以通过将orphanRemoval=true传递到@OneToOne批注来实现。

示例:

    @OneToOne(orphanRemoval=true)
    var address: UserAddress? = null

或者,您也可以使用cascade=CascadeType.REMOVE代替orphanremoval=true

ObjectDB借来:

如果指定了orphanRemoval=true,则断开连接的地址实例被自动删除。这对于清理依赖项很有用没有来自的引用就不应该存在的对象(例如地址)所有者对象(例如Employee)。如果只有cascade=CascadeType.REMOVE由于断开了与关系不是删除操作。

希望这会有所帮助!

思路二:


[我有一个类似的问题要解决时,遵循的一个很好的教程:https://www.baeldung.com/jpa-one-to-one。该教程使用Java,但是我认为您可以轻松地针对Kotlin进行调整。

您的示例缺少什么:

  • 对于User类,您需要定义@JoinColumn批注。另外,您需要定义cascade属性。
  • 对于您的UserAddress类,您需要向用户添加关系映射:mappedBy
  • 此外,如果要将列的名称保持为id,只需添加@Column(name = "id")批注。

这是适合您的情况的调整后的示例:

@Table(name = "user")
@Entity
class User (

    @Id
    @GeneratedValue(...)
    var id: Long? = null,

    // added cascade and JoinColumn
    @OneToOne(cascade = CascadeType.ALL)
    @JoinColumn(name = "user_address_id", referencedColumnName = "id")
    var address: UserAddress? = null
)

@Table(name = "user_address")
@Entity
public class UserAddress {

    @Id
    @GeneratedValue(...)
    @Column(name = "id")
    var id: Long? = null,

    // added this field
    @OneToOne(mappedBy = "user_address")
    var user: User? = null,

    (...)
}

编辑:我已经快速创建了一个Spring Boot项目,该项目具有此关系映射的有效示例:https://github.com/alexsomai/spring-boot-one-to-one。它在内存数据库中使用H2,所以我知道这不是理想的解决方案。也许您可以将其用作代码的起点。

思路三:


各种问题。

  • 映射是错误的方法。 @JoinColumn需要在另一侧,即FK。您实际上是在说地址依赖于(具有FK)地址时,您所使用的定义方式。

  • 您已经在从属实体上重新定义了@Id字段,即使它是从User实体中获取其ID的。您需要删除它并在此处通过用@Id注释关系来表明它是共享的主键关系。

用户:

@Table(name = "user")
@Entity
class User (

    @Id
    @GeneratedValue(...)
    var id: Long? = null,

    @OneToOne(cascade = [CascadeType.All], mappedBy="user")
    var address: UserAddress? = null
)

地址:

@Table(name = "user_address")
@Entity
class UserAddress(
    @Id
    @OneToOne
    @JoinColumn(name = "id", referencedColumnName = "id")
    var user: User? = null
    (...)
) 

上一篇:要在Intellij中本地提交,您是否安装git.exe

下一篇:使用Spring的POST请求下载文件?

您可能感兴趣的文章

相关阅读

热门软件源码

最新软件源码下载