无法为 Spring JPA 从类型 [java.lang.String] 转换为类型 [java.lang.Long]?
Failed to convert from type [java.lang.String] to type [java.lang.Long] for Spring JPA?
我在 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;
}
}
然后我创建一个 State Reporistory 以按国家/地区代码获取州。
@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"
我该如何解决这个问题?
您的查询混合了原生 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
您缺少 search
作为路径元素。
在我看来 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"
解法:
- 使用正则表达式模式(数字)限制
id
路径参数,或者
- 使用不同的路径查询状态(例如
/api/states?code=BR
)
后一种模式是列出和查找资源的通用标准:
- 无查询参数:列出所有
- 使用查询参数:列表匹配 -> 查找功能
所以像这样:
@GetMapping("/")
public List<State> find(@RequestParam(value = "code", required = false) String code) {
if (code != null) {
// find by code
}
else {
// list all
}
}
解决方法如下图
我用错了urlhttp://localhost:8080/api/states/findByCountryCode?code=BR
转换url
http://localhost:8080/api/states/findByCountryCode?code=BR`
至
http://localhost:8080/api/states?code=BR
我在 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;
}
}
然后我创建一个 State Reporistory 以按国家/地区代码获取州。
@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"
我该如何解决这个问题?
您的查询混合了原生 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
您缺少 search
作为路径元素。
在我看来 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"
解法:
- 使用正则表达式模式(数字)限制
id
路径参数,或者 - 使用不同的路径查询状态(例如
/api/states?code=BR
)
后一种模式是列出和查找资源的通用标准:
- 无查询参数:列出所有
- 使用查询参数:列表匹配 -> 查找功能
所以像这样:
@GetMapping("/")
public List<State> find(@RequestParam(value = "code", required = false) String code) {
if (code != null) {
// find by code
}
else {
// list all
}
}
解决方法如下图
我用错了urlhttp://localhost:8080/api/states/findByCountryCode?code=BR
转换url
http://localhost:8080/api/states/findByCountryCode?code=BR`
至
http://localhost:8080/api/states?code=BR