Modelmapper erkennt keine UUIDs
Hey, ich habe gerade angefangen, mit Modelmapper herumzuspielen, um jOOQ-Datensätze POJOs zuzuordnen.
Dies ist das Schema für die Tabelle, deren Datensätze ich konvertieren möchte (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)
);
So sieht das POJO aus:
@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);
}
}
}
Ich erstelle eine ModelMapperBean in meiner Anwendung und registriere einen UUIDKonverter dafür.
@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;
}
Ich verwende dann den Model Mapper, um ActorRecordden automatisch generierten jOOQ-Code dem POJO zuzuordnen
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());
}
Dies funktioniert, außer dass die UUID immer ist null. Zum Beispiel:
{"actor_id":null,"first_name":"John","last_name":"Doe"}
Wenn ich jedoch Folgendes ändere Builder:
public Builder withActorId(final String val) {
actorId = UUID.fromString(val);
return this;
}
Es klappt! Leider funktioniert dies nicht mit einer überladenen Methode:
public Builder withActorId(final String val) {
actorId = UUID.fromString(val);
return this;
}
public Builder withActorId(final UUID val) {
actorId = val;
return this;
}
Da kehrt auch das zurück null.
Sie können dem automatisch generierten jOOQ-Code entnehmen, dass er eine UUID verarbeiten sollte:
/**
* 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, "");
Ich bin mir nicht sicher, was mir genau fehlt. Ich möchte nicht für jede meiner Entitäten einen benutzerdefinierten Konverter erstellen, da ich viele davon habe und alle (mindestens 1) UUID enthalten. Idealerweise möchte ich das konfigurieren, um ModelMapperzu wissen, UUIDund wann immer es eines sieht, kann es damit umgehen. Vielen Dank!
HINWEIS : Ich habe dies auch mit dem Lombok- @DataObjekt versucht und es funktioniert auch nicht.
@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 {
}
}
Antworten
UUID.fromString(val)ist nicht erlaubt. Ich hatte gestern das gleiche Problem. Versuchen Sie, in ModelMapper-Konfigurationen eine in String konvertierte UUID zu verwenden.