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());

}


}