Однонаправленный @OneToOne с использованием идентификаторов - PullRequest
0 голосов
/ 25 февраля 2020

Я хочу создать @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. Я пытался использовать много разных комбинаций аннотаций, но у меня все еще была проблема с удалением. Я использую 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), удаляется только дочерний элемент , Я понятия не имею, почему ... Кроме того, я хотел бы сохранить это отношение однонаправленным.

РЕДАКТИРОВАТЬ Репозиторий пользователя

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

РЕДАКТИРОВАТЬ - РЕШЕНО ок. У меня есть другая сущность (назовем это Company), которая имеет Set<User>. Оказывается, при его получении Fetch. EAGER предотвращает удаление пользователя ... Спасибо всем за ваше время. Я понятия не имел, что это может быть проблемой, поэтому я не упомянул об этом ...

Ответы [ 2 ]

0 голосов
/ 25 февраля 2020

Различные вопросы.

  • Отображения неправильные. @JoinColumn должен быть на другой стороне, т.е. с ФК. То, как вы определили его в тот момент, когда вы фактически говорите, что Address зависит от (имеет FK to) Address.

  • Вы переопределили поле @Id в зависимом объекте. даже если он получает свой идентификатор из сущности User. Вам необходимо удалить это и указать, что это общие отношения первичного ключа здесь, аннотируя отношения с @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
    (...)
) 
0 голосов
/ 25 февраля 2020

Что вам нужно, так это каскадное удаление, которое можно получить, передав orphanRemoval=true аннотации @OneToOne.

Пример:

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

В качестве альтернативы вы также можете использовать cascade=CascadeType.REMOVE вместо orphanremoval=true.

Заимствовано из ObjectDB :

Если указано orphanRemoval=true, отключенный экземпляр адреса автоматически удаляется. Это полезно для очистки зависимых объектов (например, адреса), которые не должны существовать без ссылки от объекта-владельца (например, сотрудника). Если указано только cascade=CascadeType.REMOVE, автоматическое c действие не выполняется, поскольку отключение отношения не является операцией удаления.

Надеюсь, это поможет!

...