0

I know this has been asked many times but i really can't get a working solution.

Many keyboards and mouses have been trown thanks to this problem... >:(

I have a @ManyToOne / @OneToMany Relation: One "Service" has one and only "ServiceType", one "ServiceType" can be associated to many "Service".

problem 1): In the form where i can insert a new Service (created with thymeleaf) i have a "select" which allows me to select its "ServiceType" (each "option" has as a value the ServiceType.id). When i submit the form , i get the conversion error:

Failed to convert property value of type java.lang.String to required type com.lethal.ServiceType for property serviceType; nested exception is java.lang.IllegalStateException: Cannot convert value of type [java.lang.String] to required type [com.lethal.ServiceType] for property serviceType: no matching editors or conversion strategy found

Ok,i read on StackOverflow that i need a converter. I did this:

package com.lethal.converter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;
import org.springframework.stereotype.Component;

import com.lethal.model.ServiceType;
import com.lethal.service.ServiceTypeService; 
//the second "Service" word refers to the interface with all add/edit/delete/get.. methods..

@Component
final class StringToServiceType implements Converter<String, ServiceType> 
{

    /**
     * dependancy injection of the service
     */
    @Autowired
    private ServiceTypeService ServiceTypeService;   


    @Override
    public ServiceType convert(String id) 
    {
        /**
         * check integer type
         */
        try
        {
            Integer.parseInt(id);

            /**
             * creation of the object to return
             */
            ServiceType service_type = ServiceTypeService.getServiceType(Integer.valueOf(id));

            return service_type;
        }
        catch(NumberFormatException e)
        {
            System.out.println(e);

            return null;
        }       

    }
}

problem 2) everywhere i try to import StringToServiceType, i get the error

the type com.lethal.converter.StringToServiceType is not visible

ok... maybe i have to define it as service... as i have the configuration made in Java, i created the ConversionConfig class in the package where i have all others config classes (taken from many crud / authentication tutorials over internet):

package com.lethal.config;

import java.util.HashSet;
import java.util.Set;

import org.springframework.context.annotation.Configuration;
import org.springframework.context.support.ConversionServiceFactoryBean;
import org.springframework.core.convert.ConversionService;
import org.springframework.core.convert.converter.Converter;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.PropertySource;

import com.lethal.converter.*;
import com.lethal.converter.StringToServiceType;
/** 
* in the line above, i keep getting the 
* "type com.lethal.converter.StringToServiceType is not visible"
*  error
*/

@Configuration
public class ConversionConfig {

    @Bean(name="conversionService")
    public ConversionService getConversionService() {
        ConversionServiceFactoryBean bean = new ConversionServiceFactoryBean();
        bean.setConverters(getConverters());
        bean.afterPropertiesSet();
        ConversionService object = bean.getObject();
        return object;
    }

    private Set<Converter> getConverters() {
        Set<Converter> converters = new HashSet<Converter>();

        converters.add(new StringToServiceType());

        return converters;
    }
}

question 1): Anyone has an idea or some tutorial of converters with java based configuration ?

question 2): as i will have to do the same things for many others @ManyToMany / @OneToMany relations (for example: user / addresses , city / states,...) where i will have to put the others converters (ex. StringToState, StringToAddress) ?

thank you very much

alexbt
  • 16,415
  • 6
  • 78
  • 87
WoutVanAertTheBest
  • 800
  • 1
  • 16
  • 33
  • i tried to manually set the id in the controller, just before insert in db: _service.setId(1); ServiceService.addService(service); _ but i still get _ Cannot convert value of type [java.lang.String] to required type_ error – WoutVanAertTheBest May 28 '14 at 10:29
  • you have to make the converter class "public" (final). – Martin Frey May 28 '14 at 10:50
  • thank you @MartinFrey your adviced corrected problem #2, but i still get "no matching editors or conversion strategy found" error. i can only find tutorials with xml configuration, but i'm using java configuration – WoutVanAertTheBest May 28 '14 at 12:32

1 Answers1

0

I don't know how, and i don't know why, but i resolved in this way

(source: How to configure Spring ConversionService with java config?)

Class which implements the conversion:

package com.lethal.converter;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.convert.converter.Converter;

import com.lethal.model.ServiceType;
import com.lethal.service.ServiceTypeService;

public final class StringToServiceTypeConverter implements Converter<String, ServiceType> 
{

    @Autowired
    private ServiceTypeService ServiceTypeService;       

    @Override
    public ServiceType convert(String id) 
    {

        try
        {
            /**
            * i try to get the object from the given ID
            */

            Integer.parseInt(id);

            ServiceType servizi_tipologia = ServiceTypeService.getServiceType(Integer.valueOf(id));

            return servizi_tipologia;
        }
        catch(NumberFormatException e)
        {
            System.out.println(e);

            return null;
        }       

    }
}

my WebAppConfig.java: (where i configure the application)

package com.lethal.config;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.ComponentScan;
import org.springframework.context.annotation.Configuration;
import org.springframework.web.servlet.config.annotation.EnableWebMvc;
import org.springframework.web.servlet.config.annotation.ResourceHandlerRegistry;
import org.springframework.web.servlet.config.annotation.WebMvcConfigurerAdapter;
import org.springframework.web.servlet.view.JstlView;
import org.springframework.web.servlet.view.UrlBasedViewResolver;
import org.springframework.core.Ordered;
import org.springframework.format.FormatterRegistry;
import org.springframework.web.servlet.config.annotation.ViewControllerRegistry;

import com.lethal.converter.StringToServiceTypeConverter;

@Configuration
@EnableWebMvc
@ComponentScan("com.lethal") 
public class WebAppConfig extends WebMvcConfigurerAdapter {

    @Override
    public void addViewControllers(ViewControllerRegistry registry) {
        registry.addViewController("/login").setViewName("login");
        registry.setOrder(Ordered.HIGHEST_PRECEDENCE);
    }   

    @Bean
    public UrlBasedViewResolver setupViewResolver() {
        UrlBasedViewResolver resolver = new UrlBasedViewResolver();
        resolver.setPrefix("/WEB-INF/views/");
        resolver.setSuffix(".jsp");
        resolver.setViewClass(JstlView.class);
        return resolver;
    }

    // Maps resources path to webapp/resources
    public void addResourceHandlers(ResourceHandlerRegistry registry) {
        registry.addResourceHandler("/resources/**").addResourceLocations("/resources/");
    }



    /**
     * custom conversion
     * es. from String (id) to ServiceType 
     * 
     * step 1
     */ 
    @Bean
    public StringToServiceTypeConverter getStringToServiceTypeConverter()
    {
        return new StringToServiceTypeConverter();
    }   
    /**
     * custom conversion
     * es. from String (id) to ServiceType 
     * 
     * step 2
     */         
    @Override
    public void addFormatters(FormatterRegistry formatterRegistry)
    {
        formatterRegistry.addConverter(getStringToServiceTypeConverter());
    }

}

Honestly i don't understant why i had to add "addFormatters"... without that it doesn't work... bha

Community
  • 1
  • 1
WoutVanAertTheBest
  • 800
  • 1
  • 16
  • 33