Reputation: 21
Hi I have a little problem in java, I do not have an error but I do not get what I want. Here I create 3 Pizza with and I want to put them in a set, the problem is that when I print my set I only have One Pizza which is the first one p1.
Here's the code :
Pizza p1 = new Pizza(cannibale, Taille.Large, TypePate.Classique);
Pizza p2 = new Pizza(forestiere, Taille.XL, TypePate.Fine);
Pizza p3 = new Pizza(hypnotika, Taille.Medium, TypePate.MozzaCrust);
Set<Pizza> pizzas = new HashSet<Pizza>();
Collections.addAll(pizzas, p1,p2,p3);
Pizza
@Entity
@Table(name = "pizza")
@SequenceGenerator(name = "seqPizza", sequenceName = "seq_pizza", initialValue = 1, allocationSize = 1)
public class Pizza {
@Id
@GeneratedValue(strategy = GenerationType.SEQUENCE, generator = "seqPizza")
@Column(name = "id")
private Long id;
@ManyToOne
@JoinColumn(name = "recette", foreignKey = @ForeignKey(name = "PIZZA_RECETTE_ID_FK"))
private Recette recette;
@ManyToOne
@JoinColumn(name = "numticket_id", foreignKey = @ForeignKey(name = "PIZZA_NUMTICKET_ID_FK"))
private Commande commandePizza;
@Column(name = "prix")
private double prix;
@Enumerated(EnumType.STRING)
@Column(name = "taille_pizza")
private Taille taille;
@Enumerated(EnumType.STRING)
@Column(name = "type_pate")
private TypePate pate;
public Pizza() {
}
public Pizza(Recette recette, Taille taille, TypePate pate) {
this.recette = recette;
this.taille = taille;
this.pate = pate;
if (taille == Taille.Medium) {
this.prix = recette.getPrixM();
} else if (taille == Taille.Large) {
this.prix = recette.getPrixL();
} else {
this.prix = recette.getPrixXL();
}
if (pate == TypePate.MozzaCrust) {
this.prix = this.prix + pate.getPrix();
} else if (pate == TypePate.Pan) {
this.prix = this.prix + pate.getPrix();
} else {
this.prix = this.prix + pate.getPrix();
}
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public Commande getCommandePizza() {
return commandePizza;
}
public void setCommandePizza(Commande commandePizza) {
this.commandePizza = commandePizza;
}
public double getPrix() {
return prix;
}
public void setPrix(double prix) {
this.prix = prix;
}
public Recette getRecette() {
return recette;
}
public void setRecette(Recette recette) {
this.recette = recette;
}
public Taille getTaille() {
return taille;
}
public void setTaille(Taille taille) {
this.taille = taille;
}
public TypePate getPate() {
return pate;
}
public void setPate(TypePate pate) {
this.pate = pate;
}
@Override
public int hashCode() {
return Objects.hash(id);
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
Pizza other = (Pizza) obj;
return Objects.equals(id, other.id);
}
You can find all the code here : https://github.com/HamzaMerini/help/tree/main/pizzayolo
Thank you !!
Upvotes: 1
Views: 1166
Reputation: 2794
HashSets use the hashCode
(when equal it also uses the equals
as well) to compute identity. Your pizzas seem to have the same ID. Hence you don't provide one in the constructor nor sets one, it stay null, for all three pizzas. You could persist all those and have the database provide ids, or set them yourself.
When you use at least Java 9, you could use the utility method:
Set<Pizza> pizzas = java.util.Set.of(p1, p2, p3);
For older versions you can use:
Set<Pizza> pizzas = new HashSet<>;
pizzas.add(p1);
pizzas.add(p2);
pizzas.add(p3);
Upvotes: 1
Reputation: 4624
Even if your class is annotated with Entity
, it won't work similar way when you are instantiating object manually; i.e. while persisting Pizza
into db, you might have seen new id
got assigned to every insert / save
call because of @SequenceGenerator
.
But when you do manual instantiation of Pizza
& trying to insert it to HashSet
, it will check if there is any pre-existing Pizza
available based on hashCode
. Manual instantiation will assign default value 0
to id
& hence only first insertion to HashSet
succeed.
Change hashCode
so that it will generate some unique value & that way Collections.addAll
will work.
Upvotes: 1