Java: Hibernate @OneToOne картографиране

Опитвам се да накарам анотациите на Hibernate @OneToOne да работят и нямам много успех тук...

Да кажем, че имам таблица, наречена status, която изглежда така:

+------------------------------------------------+
|                     status                     |
+------------------------------------------------+
| id | frn_user_id | frn_content_id |   status   |
+----+-------------+----------------+------------+
|  1 |     111     |        0       |  "active"  |
+----+-------------+----------------+------------+
|  2 |      0      |       222      | "inactive" |
+----+-------------+----------------+------------+

И имам обект за User, който изглежда така:

@Entity
@Table(name = "user")
public class User {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Integer id;

    @OneToOne(cascade = CascadeType.ALL, fetch = FetchType.EAGER, mappedBy = "userId")
    private Status status;

    // getters and setters
}

И подобен за Content, и друг обект за Status, който изглежда така:

@Entity
@Table(name = "status")
public class Status {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name = "id", nullable = false)
    private Integer id;

    @Column(name = "frn_user_id")
    private Integer userId;

    @Column(name = "frn_content_id")
    private Integer contentId;

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

    // getters and setters
}

Когато извършвам четене на User, очаквам, че User.getStatus() ще върне Status обект с id=1. Вместо това получавам AnnotationException: „Референтното свойство не е (One|Many)ToOne: Status.userId в mappedBy User.status“

Прегледах документи, уроци и примери тук на SO, но всичко, което опитах досега, се провали.

Също така си струва да се отбележи: Това трябва да поддържа връзка едно към нула или едно, тъй като някои user и content записи няма да имат препратка в таблицата status.

Всяка помощ ще бъде много оценена!


person Shaun Scovil    schedule 13.02.2014    source източник
comment
userId трябва да е от тип User с @OneToOne/@JoinColumn върху него. Също така имайте предвид, че имате правописна грешка (contentId/userId)   -  person    schedule 13.02.2014
comment
вижте също stackoverflow .com/questions/18303522/   -  person    schedule 13.02.2014
comment
Просто идея за дизайн на база данни: може би бихте могли да преразгледате дизайна си като връзка много към много между потребители и съдържание и описанието на състоянието ще бъде в този дизайн потребителски атрибут?   -  person Jorge_B    schedule 13.02.2014
comment
Благодаря @RC. Не осъзнавах, че трябва да е обект.   -  person Shaun Scovil    schedule 13.02.2014
comment
@Jorge_B Да, дизайнът на DB не е идеален, но за момента съм заседнал да го използвам..   -  person Shaun Scovil    schedule 13.02.2014


Отговори (2)


Вашият обект Status не трябва да има свойства userId и contentId от тип Integer, съпоставени с @Column. Трябва да има свойства user и content от тип User и Content, съпоставени с @OneToOne:

public class User {
    @OneToOne(mappedBy = "user")
    private Status status;
    // ...
}

public class Status {
    @OneToOne
    @JoinColumn(name = "frn_user_id")
    private User user;
    // ...
}

Потребителят има един статус. Състоянието има един потребител.

person JB Nizet    schedule 13.02.2014
comment
Благодаря, че сподели това. Бях заседнал на mappedBy от последните 3 дни. Потърсих в Google и прегледах толкова много публикации в Stackoverflow за това, но никакъв успех. Когато минавам през вашето решение, си спомням, че създадох java.util.Set в OneToOne картографиране на обратната страна на релацията. Веднага след като премахнах Set и просто създадох свойство тип обект, моят код започва да работи. Много благодаря. Гласувайте за. - person OO7; 10.04.2015
comment
Малко съм объркан, след като преминах през @Vlad Mihalcea Отговор на тази публикация. В отговора си Child има many toys тогава защо е отбелязал List<Toy> toys с OneToOne(mappedBy = "child")? Защо не с OneToMany? Освен това сте посочили JoinColumn на User в Status и Влад Михалчеа не го е направил на Child в Toy. Каква е целта на mappedBy с/без JoinColumn? Ще разсеете ли съмнението ми, моля? - person OO7; 10.04.2015
comment
Грешно е. Трябва да е OneToMany. JoinColumn се използва за указване на името на колоната за присъединяване. Ако не посочите такова, Hibernate ще използва име по подразбиране (Как се конструира това име по подразбиране е указано в спецификацията на JPA) - person JB Nizet; 10.04.2015
comment
Използвах същия код, както споменахте тук. Но все пак получавам frn_user_id като нула - person viper; 24.08.2016

използвайте този начин. Добавете полето по-долу в обекта на клиента.

@OneToOne(fetch = FetchType.LAZY, cascade = CascadeType.ALL, mappedBy = "customer")
private Status status;

и не добавяйте getter и setter за полето за състояние в обекта на клиента. И добавете кода по-долу към Status Entity.

@OneToOne(fetch = FetchType.LAZY, optional = false)
@JoinColumn(name = "customer_id", nullable = false)
private Customer customer;

Тук добавете полето getter и setter за клиент в класа Status Entity. Можете да видите един работещ пример тук.

person Abhishek    schedule 02.11.2019