有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

无法将Spring JPA的[java.lang.String]类型转换为[java.lang.Long]类型?

我对在Spring JPA中实现两个以国家和州命名的实体有一个问题

我编写了一个代码来展示国家和州实体,如下所示

国家实体

@Entity
@Table(name="COUNTRY",catalog ="SPRINGANGULAR")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = {"id","code","countryName"}, exclude = "states")
public class Country {

    @Id
    @SequenceGenerator(name="COUNTRY_SEQ", sequenceName="COUNTRY_SEQ", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="COUNTRY_SEQ")
    @Column(name="ID", nullable = false)
    private long id;
    
    @Column(name="CODE")
    private String code;
    
    @Column(name="COUNTRY_NAME")
    private String countryName;
    
    @OneToMany(fetch=FetchType.LAZY,mappedBy="country",
            cascade= CascadeType.ALL)
    private Set<State> states = new HashSet<State>();

    public Country(String code, String countryName) {
        super();
        this.code = code;
        this.countryName = countryName;
    }
    
}

国家实体

@Entity
@Table(name="STATE",catalog ="SPRINGANGULAR")
@Data
@NoArgsConstructor
@AllArgsConstructor
@EqualsAndHashCode(of = {"id", "stateName"})
public class State {

    @Id
    @SequenceGenerator(name="STATE_SEQ", sequenceName="STATE_SEQ", allocationSize=1)
    @GeneratedValue(strategy=GenerationType.SEQUENCE, generator="STATE_SEQ")
    @Column(name="ID", nullable = false)
    private long id;
    
    @Column(name="STATE_NAME")
    private String stateName;
    
    @ManyToOne(fetch=FetchType.LAZY,cascade= CascadeType.ALL)
    @JoinColumn(name = "COUNTRY_ID", nullable = false)
    private Country country;

    public State(String stateName, Country country) {
        super();
        this.stateName = stateName;
        this.country = country;
    }
    
}

然后,我创建一个州报告,以按国家代码获取州

@CrossOrigin("http://localhost:4200")
@RepositoryRestResource(collectionResourceRel = "states", path = "states")
public interface StateRepository extends JpaRepository<State, Long>{

    @Query("SELECT s FROM State s \n" + 
           "LEFT JOIN Country c ON c.id = c.id \n" + 
           "WHERE c.code = :code \n" + 
           "ORDER BY s.id ASC")
    List<State> findByCountryCode(@RequestParam("code") String code);
}

然后我在Postman中编写一个连接url来检查它是否有效

http://localhost:8080/api/states/findByCountryCode?code=BR

它抛出了一个错误

Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'findByCountryCode'; nested exception is java.lang.NumberFormatException: For input string: "findByCountryCode"

我如何解决这个问题


共 (3) 个答案

  1. # 1 楼答案

    解决方案如下所示

    我错误地使用了这个url http://localhost:8080/api/states/findByCountryCode?code=BR

    转换url

    http://localhost:8080/api/states/findByCountryCode?code=BR`
    

    http://localhost:8080/api/states?code=BR
    
  2. # 2 楼答案

    您的查询是原生SQL和JPQL的混合,绝对无效。以下是有效的:

    @Query("SELECT s FROM State s \n" + 
               "WHERE s.country.code = :code \n" + 
               "ORDER BY s.id ASC")
    

    不需要显式的左连接,它是通过s.country表达式完成的

    而且,在JPQL中没有LEFT JOIN ON这样的东西Here是一些连接示例

    此外,URL应该类似于:

    http://localhost:8080/states/search/findByCountryCode?code=BR

    您缺少一个searchas路径元素

  3. # 3 楼答案

    在我看来,REST控制器有问题
    我假设你在某处有一个/api/states/{id}的映射,如下所示:

    @RestController
    @RequestMapping(path = "api/states/")
    public class StateController {
    
        @GetMapping("/{id}")
        public State getState(@PathVariable("id") long id) {
           ...
        }
    }
    

    当您调用/api/states/findByCountryCode?code=BR时,它会将findByCountryCode解释为long类型的路径变量id,这将导致此异常:

    NumberFormatException: For input string: "findByCountryCode"
    

    解决方案:

    • 用正则表达式模式(数字)限制idpath参数,或
    • 使用不同的路径查询状态(例如^{

    后一种模式是列出和查找资源的通用标准:

    • 无查询参数:列出所有
    • 带查询参数:列表匹配->;查找功能

    比如:

        @GetMapping("/")
        public List<State> find(@RequestParam(value = "code", required = false) String code) {
           if (code != null) {
               // find by code
           } 
           else {
               // list all
           }
        }