I tried to fill DB tables with random data and through Hibernate.
But my code fill incompatible data into tables (not exactly incompatible it is index of this element declared at enum, for ex: at ApartmentState
- FREE
is first element it set to appropriate column it index - 0. But I want to put or FREE
as enum or as string).
I couldn't figure out why exactly this happen.
Here is code snippet:
private List<Apartment> generateApartments() {
for (int i = 1; i <= 3; i++) {
for (int j = 2; j <= 5; j++) {
Apartment apartment = new Apartment();
// fill apartment
apartment.setRoomName(generateRoomName());
apartment.setPricePerHour(generatePrice());
apartment.setApartmentState(FREE);
apartment.setRating(getDesiredRating(j));
apartment.setSleepPlaces(getDesiredPlaces(i));
apartment.setActive(true);
// save apartment
apartments.add(apartment);
}
}
return apartments;
}
private Apartment.SleepPlaces getDesiredPlaces(int i) {
switch (i) {
case 1:
return ONE_PLACE;
case 2:
return TWO_PLACES;
case 3:
return THREE_PLACES;
}
return ONE_PLACE;
}
private Apartment.StarRating getDesiredRating(int j) {
switch (j) {
case 2:
return TWO_STARS;
case 3:
return THREE_STARS;
case 4:
return FOUR_STARS;
case 5:
return FIVE_STARS;
}
return TWO_STARS;
}
I need to fill at table some enum values, as rating (2, 3, 4) and sleep places (1, 2..).
But this puts some wrong data into table.
Here is content at workbench:
Why it puts only index, not as string or as enum.
How can I recovering this at desired value, in the future.
Here is snippet from Apartment class:
@Entity
@Table(name = "Apartments")
public class Apartment extends AbstractEntity implements Comparable<Apartment> {
private Integer id;
private String roomName;
private Double pricePerHour;
private ApartmentState apartmentState;
private StarRating rating;
private SleepPlaces sleepPlaces;
private Boolean active;
public enum ApartmentState {
FREE, REQUESTED, BOOKED, LIVED, CLEANING, PROCESSING
}
public enum StarRating {
TWO_STARS("2 stars"), THREE_STARS("3 stars"), FOUR_STARS("4 stars"), FIVE_STARS("5 stars");
private String description;
private StarRating(String description) {
this.description = description;
}
public String getDescription() {
return description;
}
}
public enum SleepPlaces {
ONE_PLACE("1 person"), TWO_PLACES("2 persons"), THREE_PLACES("3 persons"), FOUR_PLACES("4 persons");
private String count;
private SleepPlaces(String count) {
this.count = count;
}
public String getCount() {
return count;
}
}
For me the best is to put enum as enum (possibly at MySql workbench) or as a string (and use name()
and valueOf()
from Enum class).
But how to implement it with hibernate.
How to solve this trouble?
By default, Hibernate maps an enum to a number. It uses the ordinal value, which is the zero-based position of a value within the definition of the enum. So, the enum value that's defined first gets mapped to 0, the second one to 1 and so on.
ORDINAL) annotation on the enum field, JPA will use the Enum. ordinal() value when persisting a given entity in the database. A problem arises with this kind of mapping when we need to modify our enum. If we add a new value in the middle or rearrange the enum's order, we'll break the existing data model.
To map the Enum to a String database column type, you need to specify the EnumType. STRING value when using the @Enumerated annotation. As expected, the String representation of the Java Enum was used to populate the associated database column value.
By default, when an enum is a part of an entity, JPA maps its values into numbers using the ordinal() method. What it means is that without customizations JPA stores enum value as numbers. These numbers are associated with the order in which you define values in the enum.
You can add following enumeration, to indicate you want the String representation to be persisted :
@Enumerated(EnumType.STRING)
private ApartmentState apartmentState;
Use this annotation at field level:
@Enumerated(EnumType.STRING)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With