Skip to main content

Enum Mapping

Jimmer handles enums in two ways:

  • Map to string: A choice with better understandability and traceability, also the default option.

  • Map to integer: A choice with better performance-first.

Jimmer provides two annotations for enums:

  • org.babyfish.jimmer.sql.EnumType: Decorate enum types, optional

    Specify mapping method, map to string or ordinal position to integer

  • org.babyfish.jimmer.sql.EnumItem: Decorate enum items, optional

    Override the mapped string value or integer value for some enum item

Map to String

Gender.java
@EnumType(EnumType.Strategy.NAME)
public enum Gender {
MALE,
FEMALE
}

Here, the parameter of @EnumType is specified as "NAME", indicating mapping to string. By default, the mapped string values of the two enum items are the same as their names, i.e. "MALE" and "FEMALE".

If you expect the mapped strings to be different from the enum item names, you can decorate the enum items with @EnumItem.

Gender.java
@EnumType(EnumType.Strategy.NAME)
public enum Gender {

@EnumItem(name = "M")
MALE,

@EnumItem(name = "F")
FEMALE
}

Map to Integer

Gender.java
@EnumType(EnumType.Strategy.ORDINAL)
public enum Gender {
MALE,
FEMALE
}

Here, the parameter of @EnumType is specified as "ORDINAL", indicating mapping to integer. By default, the mapped integer values of the two enum items are the same as their ordinal, i.e. 0 and 1.

If you expect the mapped integers to be different from the enum items' ordinal, you can decorate the enum items with @EnumItem.

Gender.java
@EnumType(EnumType.Strategy.ORDINAL)  
public enum Gender {

@EnumItem(ordinal = 100)
MALE,

@EnumItem(ordinal = 200)
FEMALE
}

Do Not Explicitly Use @EnumType

You can also avoid specifying the @EnumType annotation for enum types, that is, not explicitly indicate whether an enum type should be mapped to string or integer.

In this case, Jimmer will refer to the default global configuration.

info

The default value of this global configuration is "NAME". If you need "ORDINAL", please override the global configuration.

Next, we show how to override the global configuration:

  • When using SpringBoot

    Add configuration item jimmer.default-enum-strategy in application.yml or application.properties and set its value to "ORDINAL"

  • When not using SpringBoot

    JSqlClient sqlClient = JSqlClient
    .newBuilder()
    .setDefaultEnumStrategy(EnumType.Strategy.ORDINAL)
    ...Omit other configurations...
    .build();

Work with TypeScript Client and Jackson

The serialization of a type to JSON and its storage in the database are two independent matters. The content described above focuses on how Jimmer handles enum mapping in the database, which is unrelated to JSON.

By default, Jackson converts enums to its name, so when generating the TypeScript Client, Jimmer maps the enum according to its name.

enum Gender {
MAN,
WOMAN
}

The generated TypeScript code is as follows:

export const GenderEnum_CONSTANTS = [
'MAN',
'WOMAN'
] as const;
export type GenderEnum = typeof GenderEnum_CONSTANTS[number];

//usage
export type PersonDto = {
gender: GenderEnum;
}

If you want to customize the JSON serialization, you need to use the @JsonValue annotation from Jackson.

enum Gender {
MAN,
WOMAN;

@JsonValue
public String getValue() {
return name().toLowerCase();
}
}

When detects the presence of annotations like @JsonValue, Jimmer not knowing how the enum will be converted during JSON serialization, so jimmer will translates the enum type to a string. The generated TypeScript code in this case is as follows:

export type PersonDto = {
gender: string;
}