Modelmapper ไม่รู้จัก UUID

Oct 26 2020

สวัสดีฉันเพิ่งเริ่มเล่นกับ Modelmapper เพื่อแมปบันทึก jOOQ กับ POJO

นี่คือสคีมาสำหรับตารางที่มีบันทึกที่ฉันพยายามจะแปลง (Postgresql)

CREATE TABLE IF NOT EXISTS actor(
    actor_id UUID DEFAULT uuid_generate_v4(),
    first_name VARCHAR(256) NOT NULL,
    last_name VARCHAR(256) NOT NULL,
    PRIMARY KEY(actor_id)
);

ลักษณะของ POJO มีดังนี้:

@JsonDeserialize(builder = Actor.Builder.class)
public class Actor {
    private final UUID actorId;
    private final String firstName;
    private final String lastName;

    private Actor(final Builder builder) {
        actorId = builder.actorId;
        firstName = builder.firstName;
        lastName = builder.lastName;
    }

    public static Builder newBuilder() {
        return new Builder();
    }

    public UUID getActorId() {
        return actorId;
    }

    public String getFirstName() {
        return firstName;
    }

    public String getLastName() {
        return lastName;
    }

    @JsonIgnoreProperties(ignoreUnknown = true)
    public static final class Builder {
        private UUID actorId;
        private String firstName;
        private String lastName;

        private Builder() {
        }

        public Builder withActorId(final UUID val) {
            actorId = val;
            return this;
        }

        public Builder withFirstName(final String val) {
            firstName = val;
            return this;
        }

        public Builder withLastName(final String val) {
            lastName = val;
            return this;
        }

        public Actor build() {
            return new Actor(this);
        }
    }
}

ฉันกำลังสร้างModelMapperbean ในแอปพลิเคชันของฉันและลงทะเบียนตัวUUIDแปลง

   @Bean
    public ModelMapper modelMapper() {
        final ModelMapper mapper = new ModelMapper();
        Provider<UUID> uuidProvider = new AbstractProvider<UUID>() {
            @Override
            public UUID get() {
                return UUID.randomUUID();
            }
        };

        final Converter<String, UUID> uuidConverter = new AbstractConverter<>() {
            @Override
            protected UUID convert(final String source) {
                return UUID.fromString(source);
            }
        };
        mapper.createTypeMap(String.class, UUID.class);
        mapper.addConverter(uuidConverter);
        mapper.getTypeMap(String.class, UUID.class).setProvider(uuidProvider);


        mapper.getConfiguration()
                .setSourceNameTokenizer(NameTokenizers.UNDERSCORE)
                .addValueReader(new RecordValueReader())
                .setDestinationNameTransformer(NameTransformers.builder("with"))
                .setDestinationNamingConvention(NamingConventions.builder("with"));
        mapper.validate();
        return mapper;
    }

จากนั้นฉันใช้ตัวทำแผนที่แบบจำลองเพื่อแมปActorRecordโค้ดที่สร้างโดยอัตโนมัติของ jOOQ กับ POJO

public Optional<Actor> getActor(final UUID actorId) {
    return Optional.ofNullable(dsl.selectFrom(ACTOR)
            .where(ACTOR.ACTOR_ID.eq(actorId))
            .fetchOne())
            .map(e -> modelMapper.map(e, Actor.Builder.class).build());
}

งานนี้ยกเว้น UUID nullอยู่เสมอ ตัวอย่างเช่น:

{"actor_id":null,"first_name":"John","last_name":"Doe"}

อย่างไรก็ตามเมื่อฉันเปลี่ยนสิ่งต่อไปนี้ในBuilder:

    public Builder withActorId(final String val) {
        actorId = UUID.fromString(val);
        return this;
    }

มันได้ผล! น่าเสียดายที่วิธีนี้ใช้ไม่ได้กับวิธีการที่มากเกินไป:

    public Builder withActorId(final String val) {
        actorId = UUID.fromString(val);
        return this;
    }

    public Builder withActorId(final UUID val) {
        actorId = val;
        return this;
    }

nullขณะที่ยังมีผลตอบแทนนี้

คุณสามารถดูได้จากโค้ด jOOQ ที่สร้างขึ้นโดยอัตโนมัติว่าควรจัดการ UUID:

/**
 * The column <code>public.actor.actor_id</code>.
 */
public final TableField<ActorRecord, UUID> ACTOR_ID = createField(DSL.name("actor_id"), org.jooq.impl.SQLDataType.UUID.nullable(false).defaultValue(org.jooq.impl.DSL.field("uuid_generate_v4()", org.jooq.impl.SQLDataType.UUID)), this, "");

ฉันไม่แน่ใจว่าตัวเองหายไปไหนกันแน่ ฉันไม่ต้องการสร้างตัวแปลงที่กำหนดเองสำหรับแต่ละเอนทิตีของฉันเนื่องจากฉันมีตัวแปลงจำนวนมากและทั้งหมดมี UUID (อย่างน้อย 1) ตามหลักการแล้วฉันต้องการกำหนดค่าสิ่งที่ModelMapperต้องรู้UUIDและเมื่อใดก็ตามที่เห็นสิ่งหนึ่งที่สามารถจัดการได้ ขอบคุณ!

หมายเหตุ : ฉันลองสิ่งนี้กับ@DataวัตถุLombok ด้วยและมันก็ไม่ได้ผลเช่นกัน

@JsonDeserialize(builder = Actor.ActorBuilder.class)
@Data
public class Actor {
    private UUID actorId;
    private String firstName;
    private String lastName;

    @JsonPOJOBuilder(withPrefix = "with")
    public static class ActorBuilder {

    }
}

คำตอบ

fr3ddie Nov 08 2020 at 11:15

UUID.fromString(val)ไม่อนุญาต ฉันมีปัญหาเดียวกันเมื่อวานนี้ ลองนำไปใช้กับการกำหนดค่า ModelMapper UUID ที่แปลงเป็น String