Hibernate — это отображение отношений

#java #hibernate #annotations #mapping

#java #гибернация #примечания #сопоставление

Вопрос:

У меня есть модель объекта (a) и некоторые другие объекты (x), такие как мобильный телефон, планшет, автомобиль и т.д.

Объекты (x) имеют первичный ключ, который ссылается на первичный ключ модели (a), поэтому объекты (x) могут принимать только значения объекта модели (a). Я говорю об отношениях IS-A.

Мне также нужно иметь доступ с обоих концов.

Мне нужна помощь с отображением в hibernate. То, что я делаю прямо сейчас, и не работает:

  • объект модели
 @Data
@Entity(name = "Model")
@Table(name = "model", schema = "mysch")
public class Model {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "model_id", columnDefinition = "BIGINT UNSIGNED")
    private long id;

    @Column(name = "description", length = 255, nullable = false, unique = true)
    private String description;

    @OneToOne(mappedBy = "model")
    private Mobile mobile;
  
  • мобильная сущность
 @Data
@Entity(name = "Mobile")
@Table(name = "mobile", schema = "mysch")
public class Mobile {

    @Id
    @Column(name = "mobile_id", columnDefinition = "BIGINT UNSIGNED")
    private long id;

    @OneToOne
    @JoinColumn(name = "mobile_id", referencedColumnName = "model_id", nullable = false, foreignKey = @ForeignKey(name = "FK_Mobile_Model"))
    private Model model;
  

Что я хочу, так это создать PK в мобильной таблице, которая ссылается на PK таблицы модели.

Комментарии:

1. Отношение кажется неправильным. Насколько я понимаю, у каждого Mobile есть-a Model , но на один Model могут ссылаться несколько Mobile s. Это верно? Если это так, вам следует использовать @ManyToOne отношение в Mobile и, возможно, @OneToMany отношение на Model .

2. Нет, извините, если мое объяснение было недостаточно хорошим. Mobile — это pk, поэтому он должен быть уникальным. Итак, предположим, что модель имеет идентификаторы: 1,2,3,4,5 . id = 1 может использоваться в мобильных устройствах. id = 2 также может использоваться в мобильных устройствах. id = 3 может использоваться в car. но id = 1 не может быть использован на мобильном устройстве во второй раз. Оба идентификатора являются PK, поэтому они уникальны..

Ответ №1:

Возможно, я нашел решение. Кажется, пока работает. Я сделаю запросы jpa позже, чтобы протестировать это. Хотя схема в БД, похоже, именно то, что я хотел. Вот что я сделал:

  • объект модели
 @Data
@Entity(name = "Model")
@Table(name = "model", schema = "sch")
public class Model {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name = "model_id", columnDefinition = "BIGINT UNSIGNED")
    private long id;

    @Column(name = "description", length = 255, nullable = false, unique = true)
    private String description;

    @OneToOne(mappedBy = "model")
    private Mobile mobile;

}
  
  • Мобильный
 @Data
@Entity(name = "Mobile")
@Table(name = "mobile", schema = "sch")
public class Mobile {

    @Id
    @Column(name = "mobile_id", columnDefinition = "BIGINT UNSIGNED")
    private long id;

    @OneToOne
    @MapsId
    private Model model;

}
  

Однако мне не нравится сгенерированное имя столбца PK для мобильного устройства… Это выглядит так:
«model_model_id».

Хотя, казалось, что это работает хорошо… Я столкнулся с проблемой. Я получаю:

 Exception in thread "JavaFX Application Thread" java.lang.StackOverflowError
at java.base/java.lang.String.equals(String.java:1009)
at com.dc.sch.entity.Model.equals(Model.java:6)
at com.dc.sch.entity.Mobile .equals(Mobile .java:6)
at com.dc.sch.entity.Model.equals(Model.java:6)
at com.dc.sch.entity.Mobile .equals(Mobile .java:6)
at com.dc.sch.entity.Model.equals(Model.java:6)
at com.dc.sch.entity.Mobile .equals(Mobile .java:6)
at com.dc.sch.entity.Model.equals(Model.java:6)