Map enum in JPA with fixed values?
For versions earlier than JPA 2.1, JPA provides only two ways to deal with enums, by their name
or by their ordinal
. And the standard JPA doesn't support custom types. So:
- If you want to do custom type conversions, you'll have to use a provider extension (with Hibernate
UserType
, EclipseLinkConverter
, etc). (the second solution). ~or~ - You'll have to use the @PrePersist and @PostLoad trick (the first solution). ~or~
- Annotate getter and setter taking and returning the
int
value ~or~ - Use an integer attribute at the entity level and perform a translation in getters and setters.
I'll illustrate the latest option (this is a basic implementation, tweak it as required):
@Entity
@Table(name = "AUTHORITY_")
public class Authority implements Serializable {
public enum Right {
READ(100), WRITE(200), EDITOR (300);
private int value;
Right(int value) { this.value = value; }
public int getValue() { return value; }
public static Right parse(int id) {
Right right = null; // Default
for (Right item : Right.values()) {
if (item.getValue()==id) {
right = item;
break;
}
}
return right;
}
};
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(name = "AUTHORITY_ID")
private Long id;
@Column(name = "RIGHT_ID")
private int rightId;
public Right getRight () {
return Right.parse(this.rightId);
}
public void setRight(Right right) {
this.rightId = right.getValue();
}
}
JPA map collection of Enums
using Hibernate you can do
@ElementCollection(targetElement = InterestsEnum.class)
@JoinTable(name = "tblInterests", joinColumns = @JoinColumn(name = "personID"))
@Column(name = "interest", nullable = false)
@Enumerated(EnumType.STRING)
Collection<InterestsEnum> interests;
How to map mysql enum type with hypen to JPA entity?
This sort of thing is what JPA Attribute Converters are designed to help achieve.
First you'll want to map your Java enum
elements to the strings found in the database, and provide a lookup method for converting a string to an element:
public enum Rating {
G("G"), // the string arguments should exactly match what's in the database.
PG("PG"),
PG13("PG-13"),
R("R"),
NC17("NC-17");
private static final Map<String, Rating> LOOKUP = Arrays.stream(values())
.collect(Collectors.toMap(Rating::getRating, Function.identity()));
private final String rating;
Rating(final String rating) {
this.rating = rating;
}
public String getRating() {
return rating;
}
public Rating fromString(final String rating) {
// You may want to include handling for the case where the given string
// doesn't map to anything - implementation is up to you.
return LOOKUP.get(rating);
}
}
Next you're going to want a class that implements javax.persistence.AttributeConverter
:
public static class RatingConverter implements AttributeConverter<Rating, String> {
@Override
public String convertToDatabaseColumn(final Rating attribute) {
return attribute.getRating();
}
@Override
public Rating convertToEntityAttribute(final String dbData) {
return Rating.fromString(dbData);
}
}
From here you need to decide whether this converter should always be applied (it sounds like it probably should be), or not.
If you want it to always be used with no further configuration from you, then annotate your converter class with @javax.persistence.Converter(autoApply = true)
.
If you want to choose when you use the converter, then you will need to add the annotation @javax.persistence.Convert(converter = RatingConverter.class)
to the Rating attribute of each JPA entity that needs it.
Personally I usually nest the converters as a static class inside the class that they convert, but you don't have to if you'd rather keep them separate.
Mapping an enum to String in R2DBC
It will map enum to string and vice versa by default without the annotation.
Related Topics
Using Mockito with Multiple Calls to the Same Method with the Same Arguments
How to Create Executable Java Program
Sorting Java Objects Using Multiple Keys
Why Does Java Have an "Unreachable Statement" Compiler Error
Difference Between Jar and War in Java
How to Force Selenium Webdriver to Click on Element Which Is Not Currently Visible
Spring Aop Not Working for Method Call Inside Another Method
Why Not to Start a Thread in the Constructor? How to Terminate
Maven - Always Download Sources and Javadocs
Why Doesn't Java Map Extend Collection
Method Chaining + Inheritance Don't Play Well Together
How to Populate a Listview in Javafx Using Custom Objects
How to Set an Image as a Background for Frame in Swing Gui of Java
Differencebetween a Javabean and a Pojo
How to Calculate the Intersection of Two Sets
How to Create Table Using Ascii in a Console
Difference Between Each Instance of Servlet and Each Thread of Servlet in Servlets