Enum (Java)
Introduction
import: jakarta vs javax
Spring Boot >= 3.0.0 uses jakarta
jakarta.persistence.AttributeConverter javax.persistence.AttributeConverter
jakarta.persistence.Converter javax.persistence.Converter
Sample w/ name only
/**
* App authorities
*/
public enum AuthorityEnum {
/***/
SUPER() {},
/***/
MONITOR_APP() {},
/***/
ROLE_ADMIN() {},
/***/
ROLE_GESTOR() {},
/***/
ROLE_MEMBRE() {};
/**
* Constructor.
*/
AuthorityEnum() {
}
/**
* Of name.
*
* @param name
* @return -
* @throws IllegalArgumentException If the this enum type has no constant with the specified name
* @throws NullPointerException If name is null
*/
public static AuthorityEnum ofName(String name) {
return AuthorityEnum.valueOf(name);
}
}
Sample w/ name, key & an additional attribute
import java.util.Optional;
import java.util.stream.Stream;
import org.springframework.lang.Nullable;
import lombok.Getter;
import lombok.val;
/**
* .
*/
@Getter
public enum NotificationIdType {
/** (short, 1st notif) Days after enrollment creation (since r2.0). */
SHORT_DAYS_AFTER_ENROLLMENT_CREATION("short_days_after_academic_record_creation", "CLAR5MAT"),
/** (short, 2nd notif) Days after teaching start of the enrollment (since r2.0). */
SHORT_DAYS_AFTER_TEACHING_START("short_days_after_teaching_start", "CLAR20IN"),
/** (short, last notif) Days before teaching end of the enrollment (since r2.0). */
SHORT_DAYS_BEFORE_TEACHING_END("short_days_before_teaching_end", "CUR2FIDO"),
/** (long, 1st notif) Days after enrollment creation (since r2.0). */
LONG_DAYS_AFTER_ENROLLMENT_CREATION("long_days_after_academic_record_creation", "CLAR5MAT"),
/** (long, 2nd notif) Days after teaching start of the enrollment (since r2.0). */
LONG_DAYS_AFTER_TEACHING_START("long_days_after_teaching_start", "CLAR20IN"),
/** (long, 3rd notif) Days after 2nd notification (since r2.0). */
LONG_DAYS_AFTER_SECOND_NOTIFICATION("long_days_after_second_notification", "LARG30MS"),
/** (long, last notif) Days before teaching end of the enrollment (since r2.0). */
LONG_DAYS_BEFORE_TEACHING_END("long_days_before_teaching_end", "LARG15AC"),
/** (long, milestone notif) Days after completing any milestone. */
LONG_DAYS_AFTER_COMPLETING_ANY_MILESTONE("long_days_after_completing_any_milestone", "LARGTANC");
/*-*/
private String key;
/*-*/
@Getter
private String templateId;
/** Constructor */
NotificationIdType(String key, String templateId) {
this.key = key;
this.templateId = templateId;
}
/**
* Of name.
*
* @param name
* @return -
* @throws IllegalArgumentException If the this enum type has no constant with the specified name
* @throws NullPointerException If name is null
*/
public static AuthorityEnum ofName(String name) {
return AuthorityEnum.valueOf(name);
}
/**
* Of key (Optional).
*
* @param key
* @return -
*/
public static Optional<NotificationIdType> ofKey(String key) {
return Stream.of(NotificationIdType.values()).parallel().filter(o -> o.getKey().equals(key))
.findAny();
}
/**
* Of key.
*
* @param key The key of the enum constant
* @return The enum constant with the specified 'key'
* @throws IllegalArgumentException If this enum doesn't have any constant with key 'key'
*/
public static NotificationIdType ofKey(String key) {
val retOpt = ofKeyOpt(key);
if (retOpt.isEmpty()) {
throw new IllegalArgumentException("No enum element w/ key: " + key);
}
return retOpt.get();
}
}
Sample converter: Entity attribute <--> DB data
When an enum is used as a type for an Entity attribute, this converter can be used to bidirectionally map with DB data.
WARNINGs:
An enum shouldn't implement AttributeConverter because it can't have a public default constructor and therefore Spring Boot fails to instantiate the bean.
At time of writing (Spring Boot 2.7.4) is very difficult to use an enum as an entity attribute type with a converter.
See, for example, https://stackoverflow.com/a/70792020/1323562
The following code is a converter for and 'AssignmentEnum' enum:
import javax.persistence.AttributeConverter;
import javax.persistence.Converter;
import org.springframework.lang.Nullable;
/**
* Enum JPA converter.<br>
*/
@Converter(autoApply = true)
public class AssignmentEnumConvert implements AttributeConverter<AssignmentEnum, String> {
/*- Entity attribute to DB field */
@Nullable
@Override
public String convertToDatabaseColumn(@Nullable AssignmentEnum value) {
String ret;
if (value == null) {
ret = null;
} else {
ret = value.getKey();
}
return ret;
}
/*- DB field to Entity attribute */
@Nullable
@Override
public AssignmentEnum convertToEntityAttribute(@Nullable String key) {
AssignmentEnum ret;
if (key == null) {
ret = null;
} else {
ret = AssignmentEnum.ofKey(key).orElseThrow();
}
return ret;
}
}
Sample enum w/ unit tests
/**
* Enumeration.<br>
* <br>
* Tips:<br>
* -Getting the name of this enum constant, exactly as declared in its enum declaration:<br>
* <instance>.name()<br>
* -Getting the enum with the specified name:<br>
* <Class>.valueOf(String) throws IllegalArgumentException,NullPointerException
*/
public enum AuthorityEnum {
/**
*
*/
SUPER {
},
/**
*
*/
ROLE_ADMIN {
},
/**
*
*/
ROLE_GESTIO {
};
}
public class AuthorityEnumTest {
/**
* Super name
*/
@Test
public void superName() {
assertEquals("SUPER", AuthorityEnum.SUPER.name());
}
/**
* Super value of
*/
@Test
public void superValueOf() {
assertEquals(AuthorityEnum.SUPER, AuthorityEnum.valueOf(AuthorityEnum.SUPER.name()));
}
/**
* Admin name
*/
@Test
public void adminName() {
assertEquals("ROLE_ADMIN", AuthorityEnum.ROLE_ADMIN.name());
}
}