JPA @Converter not being picked up for conversion

487 Views Asked by At

There is a requirement for me to persist a java object which is an attribute of a class into MySQL DB as Jason. So I am trying to convert the object to(when persisting in db)/from (when reading from Db) JSON to java object. I am using JPA @Convert annotation with a converter defined. The other attributes of the class are being persisted but the complex attribute is not converting into json string and is becoming null in db. Using JPA with mybatis

Entity Class : HomeMasterData.java


@Table(name="HomeMasterData")
@Data
@Entity
@Getter
@Setter
public class HomeMasterData {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Column(name="CustomerId", insertable = false , updatable = false)
    private int customerId;

    @Column(name="CreditLimit")
    private BigDecimal creditLimit;

    @Column(name="canBuy")
    private Boolean canBuy;

    @Column(name="EMI")
    private int Emi;

    @Column(name="metadata")
    @Convert(converter = MetadataConverter.class)
    private HomeMasterDataMetadata metadata; // This the complex attribute I am trying to persist as json
}

HomeMasterDataMetadata.java


@Getter
@Setter
@JsonIgnoreProperties(ignoreUnknown = true)
public class HomeMasterDataMetadata {
    private int total_loans;
    private int creditScore;
}


Converter


@Component
@Converter(autoApply=true)
public class MetadataConverter implements AttributeConverter<HomeMasterDataMetadata, String> {
    
    @Autowired
    ObjectMapper objectMapper;

    @SneakyThrows
    @Override
    public String convertToDatabaseColumn(HomeMasterDataMetadata homeMasterDataMetadata) {
        
            System.out.println("Converting Object to String");
            String res= objectMapper.writeValueAsString(homeMasterDataMetadata);
            return res;
    }

    @SneakyThrows
    @Override
    public HomeMasterDataMetadata convertToEntityAttribute(String s) {
       
            System.out.println("Converting String to object");
            HomeMasterDataMetadata resObj =  objectMapper.readValue(s, HomeMasterDataMetadata.class);
            return  resObj;
    }
}

MybatisMapper: userMapper.java


@Mapper
public interface userMapper {

    @Insert("Insert into CLMMasterData (CustomerId,CreditLimit,canBuy,EMI,metadata) values(#{customerId}, #{creditLimit},#{canBuy},#{Emi},#{metadata})")
    int insertCLMMasterData(HomeMasterData homeMasterData);

    @Select("select * from CLMMasterData where CustomerId = #{Id}")
    HomeMasterData getCustomerById(@Param("Id") int customerId);
}

Table Schema

CREATE TABLE HomeMasterData(
    CustomerId int Not NULL primary key auto_increment,
    CreditLimit decimal(5,2),
    canBuy Boolean,
    EMI int,
    metadata longtext
);

Controller For Inserting Records

    @PostMapping(value="/customer",produces = "application/json")
    public ResponseEntity addCustomer(@RequestBody HomeMasterData homeMasterData){
        Mapper.insertCLMMasterData(homeMasterData);
        return new ResponseEntity(HttpStatus.OK);
    }

{
    "creditLimit": 100.00,
    "canBuy": true,
    "Emi": 10,
    "metadata": {
        "total_loans": 6,
        "creditScore": 100
    }
}

whenever I am trying to run the spring application I am getting the following error.

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'userMapper' defined in file [/home/rabbani/Documents/Personal/JavaRoughProjects/MybatisComplexPersistance/target/classes/com/example/mybatiscomplexpersistance/mapper/userMapper.class]: Invocation of init method failed; nested exception is java.lang.IllegalArgumentException: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'metadata'. It was either not specified and/or could not be found for the javaType (com.example.mybatiscomplexpersistance.HomeMasterDataMetadata) : jdbcType (null) combination.
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1804) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:620) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:542) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:335) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:234) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:333) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:208) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:276) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1380) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1300) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.annotation.AutowiredAnnotationBeanPostProcessor$AutowiredFieldElement.resolveFieldValue(AutowiredAnnotationBeanPostProcessor.java:657) ~[spring-beans-5.3.10.jar:5.3.10]
    ... 25 common frames omitted
Caused by: java.lang.IllegalArgumentException: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'metadata'. It was either not specified and/or could not be found for the javaType (com.example.mybatiscomplexpersistance.HomeMasterDataMetadata) : jdbcType (null) combination.
    at org.mybatis.spring.mapper.MapperFactoryBean.checkDaoConfig(MapperFactoryBean.java:83) ~[mybatis-spring-2.0.6.jar:2.0.6]
    at org.springframework.dao.support.DaoSupport.afterPropertiesSet(DaoSupport.java:44) ~[spring-tx-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1863) ~[spring-beans-5.3.10.jar:5.3.10]
    at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1800) ~[spring-beans-5.3.10.jar:5.3.10]
    ... 35 common frames omitted
Caused by: java.lang.IllegalStateException: Type handler was null on parameter mapping for property 'metadata'. It was either not specified and/or could not be found for the javaType (com.example.mybatiscomplexpersistance.HomeMasterDataMetadata) : jdbcType (null) combination.
    at org.apache.ibatis.mapping.ParameterMapping$Builder.validate(ParameterMapping.java:119) ~[mybatis-3.5.7.jar:3.5.7]

The Application is not starting up. I need to use mybatis only and cannot migrate to any other ORM frameworks

dependency Info

<groupId>org.springframework.boot</groupId>
        <artifactId>spring-boot-starter-parent</artifactId>
        <version>2.5.5</version>
    <dependency>
            <groupId>org.springframework.boot</groupId>
            <artifactId>spring-boot-starter-data-jpa</artifactId>
        </dependency>
    <dependency>
            <groupId>org.mybatis.spring.boot</groupId>
            <artifactId>mybatis-spring-boot-starter</artifactId>
            <version>2.2.0</version>
        </dependency>

0

There are 0 best solutions below