J'ai une entité comme celle-ci
@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; } }
Et l'entité Price
est comme ça
@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; } }
Quoi J'essaie de faire est de créer une table avec le nom past_price
et elle a une relation OneToMany
avec l'entité Price
. J'ai la propriété hibernate spring.jpa.hibernate.ddl-auto = update
donc chaque fois que je l'exécute, il y a 3 tables créées 1. past_price
2. past_price_prices
et 3. prix
. Mais j'essaye seulement de créer 2 tables past_price
et price
. Toute aide serait appréciée. Merci
4 Réponses :
Problème en fait, que vous n'avez pas fourni d'autres mappages pour les entités. Comment Hibernate identifierait-il ce Price
lié à PastPrice
? Hibernate n'a pas pu (mais je ne suis pas sûr) stocker le tableau des identifiants associés dans Price
.
Par défaut, si vous ne voulez que 2 tables, vous devez ajouter un champ dans Price :
select * from Price p join PastPrice pp on pp.id = p.past_price
Dans ce cas, dans la table Price hibernate, générer une colonne avec l'identifiant du prix 'parent'. Ainsi, pour le mappage actuel, 2 tables suffiraient.
Ce serait un travail comme:
@ManyToOne(...) private PastPrice pastPrice;
dans javaDoc
Le champ qui possède la relation. Obligatoire sauf si la relation est unidirectionnelle.
en utilisant targetEntity = price.class
class pastPrice{ @OneToMany(mappedby="Price",fetch = FetchType.EAGER,cascade = CascadeType.ALL) private Set<Price> prices = null; } @Entity("Price) class Price{ }
ou en utilisant mappedby = price
class pastPrice{ @OneToMany(targetEntity=Price.class,fetch = FetchType.EAGER,cascade = CascadeType.ALL) private Set<Price> prices = null; }
Vous devez ajouter "mappedBy" pour déclarer quel champ est lié aux tables.
ajouter également ManyToOne dans l'entité Price.
Entité de prix:
@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL, mappedBy = "pastPrice") private Set<Price> prices = null;
Entité PastPrice:
@ManyToOne(fetch = FetchType.EAGER) @JoinColumn("past_price_fk") private PastPrice pastPrice;
Utilisez @JoinColumn pour indiquer à hibernate de créer une colonne dans le tableau des prix et de l'utiliser pour la jointure. Changez votre code comme suit:
@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; } }
Cela créera une colonne nommée fk_past_price dans le tableau des prix et aucune troisième table ne sera créée.
P.S .: Utilisez plutôt l'association bidirectionnelle s'il n'y a pas de raison forte d'aller avec unidirectionnel. Comme ci-dessous:
@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; } }
Prix:
@OneToMany(fetch = FetchType.EAGER,cascade = CascadeType.ALL) @JoinColumn(name = "fk_past_price") private Set<Price> prices = null;
stackoverflow.com/questions/42135114/...
Je comprends les valeurs de création ou de création-suppression des propriétés d'hibernation, mais à chaque fois, même avec des valeurs différentes, la table sera générée de la même manière.
dans
@OneToMany (fetch = FetchType.EAGER, cascade = CascadeType.ALL) private Set price = null;
ajouteztargetEntity = Price.class
celui-ci ne créera que deux prix de table et past_price.