Question: We are using ObjectMapper. When using ObjectMapper with RowMapper, should it be declared inside each mapRow (seen below), or outside of mapRow as a class public member? I assume it should be outside as a public class member per this article. [Should I declare Jackson's ObjectMapper as a static field?](https://stackoverflow.com/questions/3907929/should-i-declare-jacksons-objectmapper-as-a-static-field)

Currently using Spring boot with SQL Server database. Researching thread safety with thousands/millions of sql rows its getting.

```
List<Product> productList =  namedParameterJdbcTemplate.query(sqlQuery,
        parameters,
        new ProductMapper(productRequest));

public class ProductMapper implements RowMapper<Product> {

    @Override
    public Product mapRow(ResultSet rs, int rowNum) throws SQLException {

        ObjectMapper objectMapper = new ObjectMapper()

        Product product = new Product();

        product.setProductId(rs.getLong("ProductId"));
        product.setProductType(rs.getString("ProductType"));
        product.setLocations(objectMapper.readValue(rs.getString("Locations"), new TypeReference<List<ServiceLocation>>(){}));
            } catch (Exception e) {
                throw new ServiceException(e);
            }
        }

```

Note: Please don't ask why we are writing this manual mapper with ObjectMapper, we are doing legacy coding, and architects requested to do this.

Answer: 
An [`ObjectMapper`](https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html) instance is not immutable but, as stated in the documentation:

> 
> Mapper instances are fully thread-safe provided that ALL configuration of the instance occurs before ANY
> read or write calls.
> 
> 
> 

Which means that this code is perfectly thread-safe:

```
public class ProductMapper implements RowMapper<Product> {
    private ObjectMapper mapper;

    public ProductMapper()
    {
        objectMapper = new ObjectMapper();
    }

    @Override
    public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
        Product product = new Product();
        product.setLocations(objectMapper.readValue(rs.getString("Locations"), new TypeReference<List<ServiceLocation>>(){}));
        return product;
    }
}

```

However, the `TypeReference` object is still created for each row, which is not very efficient. A better way is to create
an [`ObjectReader`](https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectReader.html)
instance via the [`readerFor()`](https://fasterxml.github.io/jackson-databind/javadoc/2.7/com/fasterxml/jackson/databind/ObjectMapper.html#readerFor(com.fasterxml.jackson.core.type.TypeReference)) method:

```
public class ProductMapper implements RowMapper<Product> {
    private ObjectReader objectReader;

    public ProductMapper()
    {
        ObjectMapper objectMapper = new ObjectMapper();
        objectReader = objectMapper.readerFor(new TypeReference<List<ServiceLocation>>(){});
    }

    @Override
    public Product mapRow(ResultSet rs, int rowNum) throws SQLException {
        Product product = new Product();
        product.setLocations(objectReader.readValue(rs.getString("Locations")));
        return product;
    }
}

```

An `ObjectReader` instance is immutable and thread-safe.
Yes, probably you should declare it is a class level field.
It's never recommended to create redundant objects.