使用Spring Data JPA时遇到NumberFormatException异常。
使用Spring Data JPA时遇到NumberFormatException异常。
我正在使用《Spring实战5》学习Spring,并遇到了一些问题:在第3章中,当我从JDBC切换到Spring Data JPA(JDBC已经完全正常工作)时,当我尝试打开主页并查看taco的配料时,代码停止工作。我添加了一些日志以了解发生了什么,并发现findById(String id)方法无法将数据库中的值转换(或类似于此)。我正在使用MySQL。\n我尝试使用@Autowired手动调用转换器的convert(String id)方法,但我发现的唯一问题是,当键错误时,会出现另一个错误。所以数据是可见的。我将尝试在这里提供一些代码,但我不确定什么是有用的,什么是不必要的。IDE和浏览器中的错误是不同的。\n这是完整的项目:https://github.com/thedistantblue/taco-cloud-jpa\n这是我的转换器:\n
public class IngredientByIdConverter implements Converter{ private IngredientRepository ingredientRepo; @Autowired public IngredientByIdConverter(IngredientRepository ingredientRepo) { this.ingredientRepo = ingredientRepo; } @Override public Ingredient convert(String id) { log.info("在converter.convert()中:" + ingredientRepo.findById(id).toString()); Optional optionalIngredient = ingredientRepo.findById(id); return optionalIngredient.orElse(null); } }
\n控制器类:\n
@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) { Listingredients = new ArrayList<>(); log.info(converter.convert("CARN").getName()); log.info("在DTC中:" + ingredientRepository.findAll()); ingredientRepository.findAll().forEach(i -> ingredients.add(i));
\n在IDE中的错误:\njava.lang.NumberFormatException:对于输入字符串:“PROTEIN”\n在java.base/jdk.internal.math.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:2054)~[na:na]\n在java.base/jdk.internal.math.FloatingDecimal.parseDouble(FloatingDecimal.java:110)~[na:na]\n在java.base/java.lang.Double.parseDouble(Double.java:543)~[na:na]\n在浏览器中的错误:\n出现意外错误(类型=内部服务器错误,状态=500)。\n对于输入字符串:“PROTEIN”;嵌套异常是java.lang.NumberFormatException:对于输入字符串:“PROTEIN”\norg.springframework.dao.InvalidDataAccessApiUsageException:对于输入字符串:“PROTEIN”;嵌套异常是java.lang.NumberFormatException:对于输入字符串:“PROTEIN”\n在org.springframework.orm.jpa.EntityManagerFactoryUtils.convertJpaAccessExceptionIfPossible(EntityManagerFactoryUtils.java:373)
在使用Spring Data JPA时出现NumberFormatException的问题。问题的原因是在使用JPA版本的示例代码时,数据表'Ingredient'中的字段'Type'的值被错误地设置为了Integer类型,而实际上它应该是String类型。解决方法是将数据表'Ingredient'中的字段'Type'的数据类型改为String类型,以匹配JPA版本示例代码中创建Ingredient实例时使用的Ingredient.Type。
具体来说,在JPA版本示例代码中,数据的插入是通过TacoCloudApplication的dataLoader方法来完成的。在该方法中,使用Ingredient.Type来创建Ingredient实例,而不是使用String类型的值。因此,需要将数据表'Ingredient'中的字段'Type'的数据类型改为String类型,以匹配JPA版本示例代码中的数据插入操作。
如果使用JDBC版本的示例代码,则数据表'Ingredient'中的字段'Type'的值将是String类型。要查看两种方式之间的差异,可以运行TacoCloudApplication并查看表'Ingredient'。在使用JDBC版本示例代码时,字段'Type'的值将是String类型;而在使用JPA版本示例代码时,字段'Type'的值将是Integer类型。
问题:使用Spring Data JPA时出现NumberFormatException的原因以及解决方法
在使用Spring Data JPA时,有时会遇到NumberFormatException的异常。下面是一个具体的例子,描述了这个问题的出现原因和解决方法。
对于Ingredient.java,需要为字段Type type添加注解(EnumType.STRING)。
(mutable = false) private final String id; private final String name; (EnumType.STRING) private final Type type; public static enum Type { WRAP, PROTEIN, VEGGIES, CHEESE, SAUCE }
这个问题的原因是,在使用Spring Data JPA进行持久化操作时,当使用枚举类型作为实体类的属性时,如果没有使用EnumType.STRING注解,就会出现NumberFormatException异常。这是因为默认情况下,Spring Data JPA将枚举类型的值转换为整数进行存储,而不是存储枚举类型的名称。
解决这个问题的方法很简单,只需要为枚举类型的属性添加注解(EnumType.STRING)。这样,Spring Data JPA在进行持久化操作时,就会将枚举类型的值转换为字符串进行存储,而不是转换为整数。
在使用Spring Data JPA时,如果遇到NumberFormatException异常,可以检查是否为枚举类型的属性添加了(EnumType.STRING)注解。如果没有添加该注解,可以通过添加注解解决这个问题。这样,Spring Data JPA就会正确地将枚举类型的值转换为字符串进行存储,避免出现NumberFormatException异常。