简体   繁体   English

使用 ID 的单向 @OneToOne

[英]Unidirectional @OneToOne using IDs

I want to create a @OneToOne unidirectional relationship using ID's.我想使用 ID 创建@OneToOne单向关系。 Let's consider following example:让我们考虑以下示例:

@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,

    (...)
)

On database there is a foreign key constraint on user_address.id referencing user.id .在数据库上,引用user.id user_address.id有一个外键约束。 I tried using many different annotation combinations, but I still had a problem with deletion.我尝试使用许多不同的注释组合,但仍然存在删除问题。 I am using JpaRepository of User and when userRepository.deleteById(id) is called, only child ( address ) is deleted, but not a parent ( user ).我正在使用 User 的 JpaRepository 并且当userRepository.deleteById(id)被调用时,只有孩子( address )被删除,而不是父母( user )。 I would realy like to keep @Id columns with name "id".我真的很想保留名称为“id”的@Id列。 Is it even possible?甚至有可能吗?

EDIT编辑

When I use following code:当我使用以下代码时:

@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
    (...)
)

When userRepository.deleteById(id) is called, only child is deleted.userRepository.deleteById(id) ,只会删除 child。 I have no idea why... In addition I would like to keep this relation unidirectional.我不知道为什么......此外,我想保持这种关系单向。

EDIT User repository编辑用户存储库

@Repository
interface UserRepository : JpaRepository<User, Long> {
}

EDIT - SOLVED Ok.编辑 - 解决好的。 I have another entity (let's call it Company) which has Set<User> .我有另一个实体(我们称之为公司),它有Set<User> It turns out that having it Fetch.事实证明,拥有它 Fetch。 EAGER prevents the user from being deleted... Thank everyone for your time. EAGER 防止用户被删除...感谢大家的时间。 I had no idea that it might be a problem thus I haven't mentioned it...我不知道这可能是一个问题,所以我没有提到它......

What you need is a cascading delete, which you can achieve by passing orphanRemoval=true to your @OneToOne annotation.您需要的是级联删除,您可以通过将orphanRemoval=true传递给您的@OneToOne注释来实现。

Example:例子:

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

Alternatively, you could also use cascade=CascadeType.REMOVE instead of orphanremoval=true .或者,您也可以使用cascade=CascadeType.REMOVE而不是orphanremoval=true

Borrowed from ObjectDB :ObjectDB借来的:

If orphanRemoval=true is specified the disconnected Address instance is automatically removed.如果指定了orphanRemoval=true则自动删除断开连接的 Address 实例。 This is useful for cleaning up dependent objects (eg Address) that should not exist without a reference from an owner object (eg Employee).这对于清理在没有所有者对象(例如员工)的引用的情况下不应该存在的依赖对象(例如地址)很有用。 If only cascade=CascadeType.REMOVE is specified no automatic action is taken since disconnecting a relationship is not a remove operation.如果仅指定了cascade=CascadeType.REMOVE则不会采取自动操作,因为断开关系不是删除操作。

Hope this helps!希望这可以帮助!

Various issues.各种问题。

  • The mappings are the wrong way round.映射是错误的。 @JoinColumn needs to be on other side ie that with the FK. @JoinColumn需要在另一边,即与 FK。 The way you have defined it at the moment you are effectively saying that Address is dependent on (has a FK to) Address.您现在定义它的方式实际上是在说 Address 依赖于(有一个 FK to)地址。

  • You have redefined the @Id field on the dependent entity even though it derives its ID from the User entity.您已经在依赖实体上重新定义了@Id字段,即使它从User实体派生其 ID。 You need to remove that and indicate that it is a shared Primary Key relationship here by annotating the relationship with @Id .您需要删除它并通过用@Id注释关系来表明它是共享的主键关系。

Given this you will need to make this a bidirectional relationship :鉴于此,您需要将其设为双向关系:

User:用户:

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

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

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

Address:地址:

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM