简体   繁体   中英

Hibernate generates extra table

I have an Entity like this

@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;
    }

}

And the Price entity is like this

@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;
    }

}

What I am trying to do is, create a table with name past_price and it has OneToMany relationship with Price entity. I have hibernate property spring.jpa.hibernate.ddl-auto=update so whenever I run this there are 3 tables created 1. past_price 2. past_price_prices and 3. price . But I am only trying to create 2 tables past_price and price . Any help would be appreciated. Thanks

Use @JoinColumn to tell hibernate to create a column in price table and use that for joining. Change your code to below:

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

This will create a column named fk_past_price in price table and no third table will be created.

PS: Use bidirectional association instead if there's no strong reason to go with uni-directional. Like below:

@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;
    }

}

Price:

@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;
    }

}

Problem in fact, that you didn't provide other mapping for entities. How would hibernate identify that Price related to PastPrice ? Hibernate couldn't (but I'm not sure) store array of related ids in Price .

By default, if you want just 2 tables you need to add field in Price :

@ManyToOne(...)
private PastPrice pastPrice;

In this case, in table Price hibernate generate colymn with id of 'parent' price. Thus, for current mapping 2 tables would be enough.

It would be work something like:

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

in javaDoc

The field that owns the relationship. Required unless the relationship is unidirectional.

using targetEntity=price.class

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

or using mappedby=price

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

   @Entity("Price)
    class Price{
}

You should add "mappedBy" to declare which field is relate tables.

also add ManyToOne in Price entity.

Price Entity :

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

PastPrice Entity :

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM