You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在JOOQ中为自动生成的枚举添加自定义属性?

如何为JOOQ自动生成的枚举添加自定义属性?

我们已从Hibernate迁移至JOOQ数月。此前在Hibernate中,我们会编写带自定义属性的枚举,实现枚举与GUI描述的1:1映射,还能添加表征行为的属性:

public enum HBMCapacityType {

    Accepting("Accepting until end of day", true),
    Limited("Limited until end of day", true),
    AtCapacity("At Capacity until further notice",false);

    private final String description;
    private final boolean userOverridable;

    HBMCapacityType(String description, boolean userOverridable) {
        this.description = description;
        this.userOverridable = userOverridable;
    }

    public String getDescription() {
        return this.description;
    }

    public boolean isUserOverridable() {
        return this.userOverridable;
    }
}

并在Hibernate实体类中这样使用:

@Enumerated(EnumType.STRING)
@Type(type = "pg_enum")
@Column(name = "capacity_type", nullable = false, columnDefinition = "capacity_type")
private HBMCapacityType capacityType;

但JOOQ会根据PostgreSQL中的枚举自动生成仅包含字面量的枚举:

/**
 * This class is generated by jOOQ.
 */
@SuppressWarnings({ "all", "unchecked", "rawtypes" })
public enum CapacityType implements EnumType {

    Accepting("Accepting"),

    Limited("Limited"),

    AtCapacity("AtCapacity");

    private final String literal;

    private CapacityType(String literal) {
        this.literal = literal;
    }

    @Override
    public Catalog getCatalog() {
        return getSchema().getCatalog();
    }

    @Override
    public Schema getSchema() {
        return Wastecoordinator.WASTECOORDINATOR;
    }

    @Override
    public String getName() {
        return "capacity_type";
    }

    @Override
    public String getLiteral() {
        return literal;
    }

    /**
     * Lookup a value of this EnumType by its literal
     */
    public static CapacityType lookupLiteral(String literal) {
        return EnumType.lookupLiteral(CapacityType.class, literal);
    }
}

以下是几种为JOOQ自动生成的枚举添加自定义属性的可行方案:

方案一:自定义JOOQ代码生成策略

通过JOOQ的代码生成配置,修改枚举的生成逻辑,直接在生成的枚举类中添加自定义属性和方法:

  • 在JOOQ的生成配置文件(如jooq-codegen.xml)中配置自定义生成策略,继承DefaultGeneratorStrategy并重写generateEnum方法,或者使用Freemarker模板自定义枚举的生成模板。
  • 在生成逻辑中加入description、userOverridable等字段的定义,以及对应的构造方法和getter方法。
    这种方式能让生成的枚举直接拥有所需属性,长期维护更便捷,无需额外工具类。

方案二:编写枚举扩展工具类

不修改自动生成的枚举,而是创建一个工具类来映射枚举值与自定义属性:

public class CapacityTypeExtensions {
    private static final Map<CapacityType, String> DESCRIPTION_MAP = Map.of(
        CapacityType.Accepting, "Accepting until end of day",
        CapacityType.Limited, "Limited until end of day",
        CapacityType.AtCapacity, "At Capacity until further notice"
    );

    private static final Map<CapacityType, Boolean> OVERRIDABLE_MAP = Map.of(
        CapacityType.Accepting, true,
        CapacityType.Limited, true,
        CapacityType.AtCapacity, false
    );

    public static String getDescription(CapacityType type) {
        return DESCRIPTION_MAP.get(type);
    }

    public static boolean isUserOverridable(CapacityType type) {
        return OVERRIDABLE_MAP.get(type);
    }
}

使用时直接调用工具类方法:CapacityTypeExtensions.getDescription(capacityType),这种方式无需改动JOOQ生成逻辑,实现快速,适合临时需求或枚举值变动较少的场景。

方案三:利用Java接口默认方法

定义一个包含所需属性方法的接口,再让JOOQ生成的枚举实现该接口:

  1. 创建接口:
public interface CapacityTypeProperties {
    default String getDescription() {
        return switch ((CapacityType) this) {
            case Accepting -> "Accepting until end of day";
            case Limited -> "Limited until end of day";
            case AtCapacity -> "At Capacity until further notice";
        };
    }

    default boolean isUserOverridable() {
        return switch ((CapacityType) this) {
            case Accepting, Limited -> true;
            case AtCapacity -> false;
        };
    }
}
  1. 修改JOOQ生成配置,让自动生成的CapacityType枚举实现CapacityTypeProperties接口(可通过自定义生成策略实现,避免每次生成后手动修改)。
    这种方式代码更优雅,调用方式和Hibernate时期一致:capacityType.getDescription(),同时保留JOOQ自动生成的特性。

内容的提问来源于stack exchange,提问作者benstpierre

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.09 06:45:31