使用Spring Data JPA获取NumberFormatException

时间:2019-07-08 20:29:32

标签: java spring jpa numberformatexception

我正在使用“ Spring in action 5”来学习Spring并遇到一些问题:当我在第3章中从JDBC切换到Spring Data JPA(100%正常工作)时,代码在我尝试打开时停止工作主页上有炸玉米饼的成分。我做了一些日志以查看发生了什么,发现方法findById(String id)无法从DB(或类似的东西)转换我的值。我正在使用MySQL。

我尝试使用@Autowired自己调用转换器的方法convert(String id),但我发现的唯一发现是,当密钥错误时,将出现另一个错误。因此数据可见。我将在此处尝试提供一些代码,但是我不确定什么有用,什么没有。第一次尝试记录某些内容时出现错误。 IDE和浏览器中的错误有所不同。 这是完整的项目https://github.com/thedistantblue/taco-cloud-jpa

这是我的转换器:

    public class IngredientByIdConverter implements Converter<String, 
    Ingredient> {

    private IngredientRepository ingredientRepo;

    @Autowired
    public IngredientByIdConverter(IngredientRepository ingredientRepo) {
        this.ingredientRepo = ingredientRepo;

    }
    @Override
        public Ingredient convert(String id) {
            log.info("In converter.convert(): " 
        +ingredientRepo.findById(id).toString());
            Optional<Ingredient> optionalIngredient = 
        ingredientRepo.findById(id);
            return optionalIngredient.orElse(null);
        }
    }

和控制器类:

    @Slf4j
    @Controller
    @RequestMapping("/design")
    @SessionAttributes("order")
    public class DesignTacoController {

    @ModelAttribute(name = "order")
    public Order order() {
        return new Order();
    }

    @ModelAttribute(name = "taco")
    public Taco taco() {
        return new Taco();
    }

    private final IngredientRepository ingredientRepository;
    private TacoRepository designRepository;
    private IngredientByIdConverter converter;

    @Autowired
    public DesignTacoController(IngredientRepository ingredientRepository,
                                TacoRepository designRepository,
                                IngredientByIdConverter converter) {
        this.ingredientRepository = ingredientRepository;
        this.designRepository = designRepository;
        this.converter = converter;
    }

    @GetMapping
    public String showDesignForm(Model model) {
        List<Ingredient> ingredients = new ArrayList<>();



        log.info(converter.convert("CARN").getName());
        log.info("in DTC: " + ingredientRepository.findAll());

        ingredientRepository.findAll().forEach(i -> ingredients.add(i));

在IDE中:

java.lang.NumberFormatException:对于输入字符串:“ PROTEIN”  在java.base / jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)〜[na:na]     在java.base / jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)〜[na:na]     在java.base / java.lang.Double.parseDouble(Double.java:543)〜[na:na]

在浏览器中:

发生意外错误(类型=内部服务器错误,状态= 500)。 对于输入字符串:“ PROTEIN”;嵌套的异常是java.lang.NumberFormatException:对于输入字符串:“ PROTEIN” org.springframework.dao.InvalidDataAccessApiUsageException:对于输入字符串:“ PROTEIN”;嵌套的异常是java.lang.NumberFormatException:对于输入字符串:“ PROTEIN”     在org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:373)处     在org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:255)     在org.springframework.orm.jpa.AbstractEntityManagerFactoryBean.translateExceptionIfPossible(AbstractEntityManagerFactoryBean.java:527)     在org.springframework.dao.support.ChainedPersistenceExceptionTranslator.translateExceptionIfPossible(ChainedPersistenceExceptionTranslator.java:61)     在org.springframework.dao.support.DataAccessUtils.translateIfNecessary(DataAccessUtils.java:242)     在org.springframework.dao.support.PersistenceExceptionTranslationInterceptor.invoke(PersistenceExceptionTranslationInterceptor.java:153)     在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186)

2 个答案:

答案 0 :(得分:1)

对于Ingredient.java,需要为字段Type type添加注释@Enumerated(EnumType.STRING)

@Id
@NaturalId(mutable = false)
private final String id;
private final String name;
@Enumerated(EnumType.STRING)
private final Type type;

public static enum Type {
    WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE
}

答案 1 :(得分:0)

@Pavel的解决方案确实有效。

我只想指出,还有另一件事,可能值得检查。

本书讨论JPA之前的JDBC,并使用data.sql将数据插入表'Ingredient'中。在文件data.sql中,“ Ingredient.Type”的类型为字符串。

其值包含“ WRAP”,“ PROTEIN”等。

但是,在JPA的示例中,data.sql的内容被移动到TacoCloudApplication中,该内容写在方法“ dataLoader”中,在此方法中,您可以看到它只是使用Ingredient.Type创建了成分实例。 (不是字符串)。

要找到两种方法之间的区别,可以运行TacoCloudApplication,然后查找表'Ingredient'。

如果使用JDBC版本示例代码,则Type字段的值为String。如果使用的是JPA版本示例代码,则Type字段的值为Interger。