Why MyBatis can't map the JSONB type to a Map<String, Object> or to JsonNode?

Kambei

I have a DTO as:

@Data
@Accessors(chain = true)
public class UserHasAssetDTO {

    private Integer id;

    ...

    private Map<String, Object> props;
}

and a Repository where I have the method:

@Select("select id, ..., props from bla bla bla")
List<UserHasAssetDTO> getALLAssetsFilteredByDate(@Param("username") String username, @Param("startDate") String startDate, @Param("endDate") String endDate);

Note: the field props in my PostgreSQL DB is JSONB type.

If I execute the query manually, I can see that the props are populated correctly.

But, when in my service:

    public List<UserHasAssetDTO> userHasALLAssets(String user, String start, String end) {

        List<UserHasAssetDTO> userHasAssetDTOList = userHasAssetRepository.getALLAssetsFilteredByDate(user, start, end);

        log.info("userHasALLAssets: {}", userHasAssetDTOList);

        return userHasAssetDTOList;
    }

The props fields ar null!!!

I suspect that I am not mapping PostgreSQL's JSONB type correctly on my DTO.

How can I fix it so that the props fields are populated correctly?

Kambei

Solved with this Class:

@MappedJdbcTypes({JdbcType.JAVA_OBJECT})
@MappedTypes({JsonNode.class})
public class JsonNodeTypeHandler extends BaseTypeHandler<JsonNode> {

    private static final ObjectMapper objectMapper = new ObjectMapper();

    @Override
    public void setNonNullParameter(PreparedStatement ps, int i, JsonNode parameter, JdbcType jdbcType)
            throws SQLException {
        PGobject jsonObject = new PGobject();
        jsonObject.setType("jsonb");
        try {
            jsonObject.setValue(parameter.toString());
            ps.setObject(i, jsonObject);
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
    }

    @Override
    public JsonNode getNullableResult(ResultSet rs, String columnName) throws SQLException {
        String jsonSource = rs.getString(columnName);
        if (jsonSource != null) {
            try {
                return objectMapper.readTree(jsonSource);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    @Override
    public JsonNode getNullableResult(ResultSet rs, int columnIndex) throws SQLException {
        String jsonSource = rs.getString(columnIndex);
        if (jsonSource != null) {
            try {
                return objectMapper.readTree(jsonSource);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }

    @Override
    public JsonNode getNullableResult(CallableStatement cs, int columnIndex) throws SQLException {
        String jsonSource = cs.getString(columnIndex);
        if (jsonSource != null) {
            try {
                return objectMapper.readTree(jsonSource);
            } catch (Exception e) {
                throw new RuntimeException(e);
            }
        }
        return null;
    }
}

and JsonNode type in my DTO.

Collected from the Internet

Please contact [email protected] to delete if infringement.

edited at
0

Comments

0 comments
Login to comment

Related

MyBatis: Map String to boolean

Convert JsonNode object to Map

why i can't create a Map of String and generic object

Can't use underlying type of string inside map of string: "cannot use <xxx> (type <yyy>) as type string in map index"

Map a JsonNode object to a String field in SQL DB JPA

Why can't I key in a string in Golang map?

Map string properties to JSONB

Why can't I serialize Map[String,Any] to JSON?

Why i can`t change my object with .map from mongo?

Why can't I use a map iterating and object by its keys?

Can't spread on a custom object map type

Flutter-Firestore "The argument type 'Map<String, dynamic> Function()' can't be assigned to the parameter type 'Map<String, dynamic>"

Why can't I add a (String -> JsBoolean) to a Map[String, JsValue]?

The argument type 'Map<String, dynamic> Function()' can't be assigned to the parameter type 'Map<String, dynamic>'

Why can't I use for in loop on a map object

Why I can't use the std::map[ ] to add a string, but std::map.at() works?

Flutter : Facing an error like - The argument type 'Map<String, dynamic>?' can't be assigned to the parameter type 'Map<String, Object?>'

Flutter - A value of type 'List<Map<String, Object>>' can't be assigned to a variable of type 'List<Classes>'

The argument type 'Map<dynamic, dynamic>' can't be assigned to the parameter type 'Map<String, dynamic>'

The argument type 'Map<String, Object>' can't be assigned to the parameter type 'String'.dartargument_type_not_assignable

A value of type 'Set<String?>' can't be assigned to a variable of type 'Map<String, String>'

The argument type 'Map<dynamic, dynamic>' can't be assigned to the parameter type 'Map<String, dynamic>'. error showing in flutter

The argument type Set<Map<String, Widget Function(BuildContext)>> can't be assigned to the parameter type 'Map<String, Widget Function(BuildContext)>

The argument type 'Iterable<Map<String, dynamic>>' can't be assigned to the parameter type 'List<Map<String, dynamic>>'

Flutter Convert FromMap to list The argument type 'Object?' can't be assigned to the parameter type 'Map<String, dynamic>'

The argument type 'Object' can't be assigned to the parameter type 'Map<String, dynamic>'

A value of type 'Future<QuerySnapshot<Map<String, dynamic>>>' can't be assigned to a variable of type 'QuerySnapshot<Object?>'

The argument type 'CollectionReference<Object?>' can't be assigned to the parameter type 'Query<Map<String, dynamic>>'. (Documentation)

Getting this error: "The argument type 'Object?' can't be assigned to the parameter type 'List<Map<String, Object>>'."