1

How do I convert JSON String stored in a DB column to a Map<String, ?> attribute defined in entity class Product?

I have defined a @ReadingConverter JsonToMapConverter class and a ProductRepository. Calling productRepository.findAll() throws error org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class java.lang.Object!

@Table("product")
public class Product {
    @Id
    private BigInteger id;
    private String Map<String, ?> metaData;

    // Getters / Setters here
}

@ReadingConverter
public class JsonToMapConverter implements Converter<String, Map<String, ?>> {
    private static final ObjectMapper objectMapper = new ObjectMapper();
    @SneakyThrows
    @Override
    public Map<String, ?> convert(String s) {
        return objectMapper.readValue(s, Map.class);
    }
}

@Repository
public interface ProductRepository extends CrudRepository<Product, BigInteger> {}

@SpringBootTest
class ProductTest {

    @Autowired
    private ProductRepository productRepository;

    @Test
    public void fetchProducts() {
        // Throws org.springframework.data.mapping.MappingException: Couldn't find PersistentEntity for type class java.lang.Object!
        productRepository.findAll();
    }
}

mysql> select * from product;
+----+-----------+
| id | meta_data |
+----+-----------+
|  1 | {}        |
+----+-----------+
user2176499
  • 363
  • 3
  • 16
  • Does this answer your question? [Map single column mapping in spring data jdbc](https://stackoverflow.com/questions/58910098/mapstring-string-single-column-mapping-in-spring-data-jdbc) – Jens Schauder May 03 '21 at 14:20

1 Answers1

2

Looking at the post I can infer that you are trying to convert String to Map and vice versa in order to read and store in Database.

Here is a sample code that can be helpful in this case.


@Converter
public class StringMapConverter implements AttributeConverter<Map<String, String>, String> {

    private static final ObjectMapper mapper  = new ObjectMapper();

    @SneakyThrows(IOException.class)
    @Override
    public String convertToDatabaseColumn(Map<String, String> data) {
        if (null == data) {
            return "{}";
        }
        return mapper.writeValueAsString(data);
    }

    @SneakyThrows(IOException.class)
    @Override
    public Map<String, String> convertToEntityAttribute(String s) {
        if (null == s) {
            return new HashMap<>();
        }
        return mapper.readValue(s, new TypeReference<>() {
        });
    }
}

Also in order to use this an Annotaion is required in entity class at the field level.

Hence it will go like this.


@Table("product")
public class Product {
    @Id
    private BigInteger id;
    @Convert(converter = StringMapConverter.class) 
    private String Map<String, ?> metaData;

    // Getters / Setters here
}
vijaydeep
  • 395
  • 3
  • 12