Як я можу позначити обмеження зовнішнього ключа за допомогою анотацій Hibernate?


76

Я намагаюся використовувати анотацію Hibernate для написання класу моделі для моїх таблиць бази даних.

У мене є дві таблиці, кожна з яких має первинний ключ Користувач та Питання.

@Entity
@Table(name="USER")
public class User
{
    @Id
    @Column(name="user_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private Long id;

    @Column(name="username")
    private String username;

    // Getter and setter
}

Таблиця запитань.

@Entity
@Table(name="QUESTION")
public class Questions extends BaseEntity{

    @Id
    @Column(name="question_id")
    @GeneratedValue(strategy=GenerationType.AUTO)
    private int id;

    @Column(name="question_text")
    private String question_text;

    // Getter and setter
}

І у мене є ще одна таблиця UserAnswer, яка має userId та questionId як зовнішні ключі з двох вищезазначених таблиць.

Але я не можу знайти, як я можу посилатися на ці обмеження в таблиці UserAnswer.

@Entity
@Table(name="UserAnswer ")
public class UserAnswer
{
    @Column(name="user_id")
    private User user;

    //@ManyToMany
    @Column(name="question_id")
    private Questions questions ;

    @Column(name="response")
    private String response;

    // Getter and setter
}

Як я можу цього досягти?

Відповіді:


68

@Columnне є відповідною анотацією. Ви не хочете зберігати цілого користувача чи запитання у стовпці. Ви хочете створити асоціацію між сутностями. Почніть з перейменування Questionsна Question, оскільки екземпляр представляє одне питання, а не кілька. Потім створіть асоціацію:

@Entity
@Table(name = "UserAnswer")
public class UserAnswer {

    // this entity needs an ID:
    @Id
    @Column(name="useranswer_id")
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @ManyToOne
    @JoinColumn(name = "user_id")
    private User user;

    @ManyToOne
    @JoinColumn(name = "question_id")
    private Question question;

    @Column(name = "response")
    private String response;

    //getter and setter 
}

Документація про сплячий режим пояснює це. Читати. А також прочитайте javadoc анотацій.


Щиро дякую за відповідь. Чи потрібно створювати новий стовпець у таблиці як useranswer_id? Чи можливо, якщо я можу зробити інші два ідентифікатори як складені ключі?
vikiiii

3
Це можливо, але це поганий дизайн, болючий, важкий у використанні та неефективний. Робіть правильно, і призначте автоматично згенерований ідентифікатор з одним стовпцем усім вашим об’єктам.
JB Nizet

@JB_Nizet Я не проти додати стовпець ідентифікатора до сутності. Але чи потрібно також додавати стовпець у таблицю? Я маю на увазі базу даних oracle.
vikiiii

Так, звісно. Де Hibernate зберігає ідентифікатор сутності, якщо відповідний стовпець не існує?
JB Nizet

Я попросив керівника своєї команди. Я не можу додати стовпець. Я повинен зробити їх складеними клавішами. Я спробував використовувати @ EmbeddedId та @ Embeddable. Але я отримую виняток сплячого режиму
vikiiii

6

Відповідей багато, і всі вони також правильні. Але, на жаль, жоден з них не має чіткого пояснення.

Наступне також працює для відображення непервинного ключа.

Скажімо, у нас є батьківська таблиця A зі стовпцем 1 та інша таблиця B зі стовпцем 2, який посилається на стовпець 1:

@ManyToOne
@JoinColumn(name = "TableBColumn", referencedColumnName = "TableAColumn")
private TableA session_UserName;

Введіть тут опис зображення

@ManyToOne
@JoinColumn(name = "bok_aut_id", referencedColumnName = "aut_id")
private Author bok_aut_id;

2

@JoinColumn(name="reference_column_name") анотація може бути використана над тим властивістю або полем класу, на яке посилається якась інша сутність.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.