Skip to content

[Feature Request] - Add information about AbstractScalarProvider for working with JSON to the documentation #894

Open
@storympro

Description

Reason

I couldn't find an explanation for working with jsonb to make the custom field type work correctly.

https://babyfish-ct.github.io/jimmer-doc/docs/configuration/scala-provider

Description

I have custom type:

import com.fasterxml.jackson.annotation.JsonValue;

import java.io.Serializable;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;

public class Translation implements Serializable {
    private final Map<String, String> translation;

    public Translation() {
        this.translation = new HashMap<>();
    }

    public Translation(Map<String, String> translation) {
        this.translation = new HashMap<>(translation);
    }

    public Translation set(String lang, String value) {
        this.translation.put(lang, value);
        return this;
    }

    public String get(String lang) {
        return this.translation.get(lang);
    }

    @JsonValue
    public Map<String, String> get() {
        return Collections.unmodifiableMap(this.translation);
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Translation that = (Translation) o;
        return Objects.equals(translation, that.translation);
    }

    @Override
    public int hashCode() {
        return Objects.hash(translation);
    }

    @Override
    public String toString() {
        return "Translation{" +
                "translation=" + translation +
                '}';
    }
}

Implemented and working AbstractScalarProvider

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import org.babyfish.jimmer.sql.runtime.AbstractScalarProvider;
import org.springframework.stereotype.Component;

@Component
public class TranslationScalarProvider extends AbstractScalarProvider<Translation, String> {
    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public Translation toScalar(String sqlValue) throws JsonProcessingException {
        if (sqlValue.isEmpty()) {
            return new Translation();
        }

        return new Translation(objectMapper.readValue(sqlValue, new TypeReference<>() {
        }));
    }

    @Override
    public String toSql(Translation scalarValue) throws JsonProcessingException {
        return objectMapper.writeValueAsString(scalarValue.get());
    }

    @Override
    public boolean isJsonScalar() { ///////////////////////// IS REQUIRED
        return true;                           ///////////////////////// NEED TRUE
    }
}

My entity

@Entity
public interface Example {

    /**
     * Назва
     */
    @Nonnull
    //@Serialized ///////////////////////// REMOVE IT
    Translation name();

    /**
     * Опис
     */
    @Nonnull
    //@Serialized ///////////////////////// REMOVE IT
    Translation description();
}

If you leave @serialized , then in the absence of isJsonScalar() it will return a value, but there will be an error when inserting the field.

Existing solutions

No response

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions