Hibernate создает дополнительную таблицу - PullRequest
2 голосов
/ 11 марта 2019

У меня есть такая сущность

@Entity
@Table(name = "past_price")
public class PastPrice {

    @Id
    private String symbol;
    @OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
    private Set<Price> prices = null;

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public Set<Price> getPrices() {
        return prices;
    }

    public void setPrices(Set<Price> prices) {
        this.prices = prices;
    }

}

А Price сущность такая же

@Entity
public class Price {
    @Id
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;
    private String price;

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

}

Я пытаюсь создать таблицу с именем past_price, которая имеет отношение OneToMany к сущности Price. У меня есть свойство hibernate spring.jpa.hibernate.ddl-auto=update, поэтому, когда я запускаю его, создаются 3 таблицы 1. past_price 2. past_price_prices и 3. price. Но я только пытаюсь создать 2 таблицы past_price и price. Любая помощь будет оценена. Спасибо

Ответы [ 4 ]

1 голос
/ 11 марта 2019

Используйте @JoinColumn, чтобы сообщить hibernate о создании столбца в таблице цен, и используйте его для объединения. Измените свой код ниже:

@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL)
@JoinColumn(name = "fk_past_price")
private Set<Price> prices = null;

Это создаст столбец с именем fk_past_price в таблице цен, и третья таблица не будет создана.

P.S .: Вместо этого используйте двунаправленную связь, если нет веских причин для однонаправленной связи. Как ниже:

@Entity
@Table(name = "past_price")
public class PastPrice {

    @Id
    private String symbol;
    @OneToMany(mappedBy = "pastPrice", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
    private Set<Price> prices = null;

    public String getSymbol() {
        return symbol;
    }

    public void setSymbol(String symbol) {
        this.symbol = symbol;
    }

    public Set<Price> getPrices() {
        return prices;
    }

    public void setPrices(Set<Price> prices) {
        this.prices = prices;
    }

}

Цена:

@Entity
public class Price {
    @Id
    @Temporal(TemporalType.TIMESTAMP)
    private Date date;
    private String price;

    @ManyToOne
    @JoinColumn(name = "past_price_symbol", nullable = false)
    private PastPrice pastPrice;

    public PastPrice getPastPrice() {
      return pastPrice;
    }

    public void setPastPrice(PastPrice pastPrice) {
      this.pastPrice = pastPrice;
    }

    public Date getDate() {
        return date;
    }

    public void setDate(Date date) {
        this.date = date;
    }

    public String getPrice() {
        return price;
    }

    public void setPrice(String price) {
        this.price = price;
    }

}
0 голосов
/ 11 марта 2019

в javaDoc

Поле, которому принадлежат отношения. Требуется, если отношения не являются однонаправленными.

с использованием targetEntity = price.class

 class pastPrice{
         @OneToMany(targetEntity=Price.class,fetch = FetchType.EAGER,cascade = CascadeType.ALL)
         private Set<Price> prices = null;
    }

или используя mappedby = цена

class pastPrice{
     @OneToMany(mappedby="Price",fetch = FetchType.EAGER,cascade = CascadeType.ALL)
      private Set<Price> prices = null;
}

   @Entity("Price)
    class Price{
}
0 голосов
/ 11 марта 2019

Вы должны добавить «mappedBy», чтобы объявить, какое поле является связанными таблицами.

также добавить ManyToOne в объекте Price.

Объект Entity:

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn("past_price_fk")
private PastPrice pastPrice;

Объект PastPrice:

@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL, mappedBy = "pastPrice")
private Set<Price> prices = null;
0 голосов
/ 11 марта 2019

Фактически проблема в том, что вы не предоставили другое сопоставление сущностям Как в спящем режиме можно определить, что Price относится к PastPrice? Hibernate не может (но я не уверен) хранить массив связанных идентификаторов в Price.

По умолчанию, если вам нужно всего 2 таблицы, вам нужно добавить поле в Price:

@ManyToOne(...)
private PastPrice pastPrice;

В этом случае в таблице Price hibernate генерирует colymn с идентификатором «родительской» цены. Таким образом, для текущего отображения достаточно двух таблиц.

Было бы работать что-то вроде:

select * from Price p join PastPrice pp on pp.id = p.past_price
...