2

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

theanilpaudel
  • 3,348
  • 8
  • 39
  • 67
  • https://stackoverflow.com/questions/42135114/how-does-exactly-spring-jpa-hibernate-ddl-auto-property-works-in-spring/42147995 – Akash Shah Mar 11 '19 at 05:47
  • I understand the create or create-drop values of hibernate properties but every time even with different values the table will be generated in the same way. – theanilpaudel Mar 11 '19 at 05:49
  • in `@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL) private Set prices = null;` add `targetEntity = Price.class` this one will create only two table price and past_price. – Akash Shah Mar 11 '19 at 05:57

4 Answers4

1

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.

P.S.: 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;
    }

}
Aditya Narayan Dixit
  • 2,105
  • 11
  • 23
0

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
ZhenyaM
  • 676
  • 1
  • 5
  • 15
0

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{
}
Akash Shah
  • 596
  • 4
  • 17
0

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;