Hibernate, вопрос про Join'ы

251
29 декабря 2017, 00:33

Все никак не могу понять логику того, как JoinColumn определяет какую колонку с какой надо связать.

@Entity
@Table(name = "BETS")
public class Bet {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id_bet") // Primary Key
private int id_bet;
@Column(name = "id_result")
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "id_result")
private int id_result;
@Column(name = "bet_on")
private String bet_on;
@Column(name = "amount")
private int amount;
public Bet() {
}
public void setResultId(int id_result) {
    this.id_result = id_result;
}
public void setBetOn(String bet_on) {
    this.bet_on = bet_on;
}
public void setAmount(int amount) {
    this.amount = amount;
}
public int getBetId() {
    return id_bet;
}
public int getResultId() {
    return id_result;
}
public String getBetOn() {
    return bet_on;
}
public int getAmount() {
    return amount;
}

И вот этого:

@Entity
@Table(name = "RESULTS")
public class Result {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE)
@Column(name = "id_result")  //Primary Key
private static short id_result;
@OneToMany(fetch = FetchType.LAZY)
@Column(name = "id_event")
private short id_event;
@Column(name = "winner")
private String winner;
@Column(name = "multiplier")
private double multiplier;
public void setEventId(short id_event) {
    this.id_event = id_event;
}
public void setWinner(String winner) {
    this.winner = winner;
}
public void multiplier(double multiplier) {
    this.multiplier = multiplier;
}
public int getResultId() {
    return id_result;
}
public int getEventId() {
    return id_event;
}
public String getWinner() {
    return winner;
}
public double getMultiplier() {
    return multiplier;
}

Надо связать классы по id_result(Bets) -> id_result(Results)

Answer 1

Коротко: в @JoinColumn вы указываете имя колонки, в которой находится id присоединяемой сущности.

Используя аннотацию @ManyToOne вы просите hibernate положить в это поле набор соответствующих объектов.

Поэтому вам надо поменять:

private int id_result;

на:

private Result result;

В этом случае hibernate будет вытаскивать объект Bet и добавлять к нему объект Result.

В аннотации @JoinColumn вы указываете имя колонки, которая ссылается на Primary Key таблицы с результатами. Когда hibernate видит эту аннотацию, он смотрит в какой таблице лежит объект Result и достает оттуда значение по указаyному id.

Это проще объяснить на примере jdbc.

Есть запрос SELECT * FROM BETS as b LEFT JOIN RESULTS as r ON b.id_result=r.id_result;

Из него мы получаем таблицу в которой есть все поля относящиеся к Bet и к Result. Идем по результату построчно и разбираем каждую строку на объект:

while(resultList.next()){
    Bet bet = new Bet();
    bet.setIdBet(resultList.getInt("id_bet"));
    //мапим все поля bet через сеттеры, кроме result
    Result result = new Result();
    result.setIdResult(resultList.getInt("id_result"));
    //мапим все поля result через сеттеры
    bet.setResult(result);
    //теперь у нас есть полностью готовый объект bet     
}

Hibernate все это делает за вас (+ ленивую загрузку). Т.е. в @JoinColumn вы указываете колонку, которая в JOIN будет равна id присоединяемой таблицы.

READ ALSO
Не делается запрос в базу SQLite

Не делается запрос в базу SQLite

ЗдравствуйтеВ проекте было много текста (bb

279
Разбить строку на слова java

Разбить строку на слова java

Здравствуйте, помогите Я прочитал строку из файла и теперь мне надо разбить ее на слова по пробелу, так же в слове поменять буквы местами и записать...

276
Как обновить ACCESS-TOKEN в Retrofit2/RxJava2

Как обновить ACCESS-TOKEN в Retrofit2/RxJava2

Я делаю запрос (любой, авторизация, регистрация и тд) и только потом узнаю, что нужно обновить TOKEN, то есть получаю ошибку 401

279