Spring Boot REST Hibernate - 创建用户

4
我试图在后端创建一个用于创建用户的函数,我使用了Spring Boot、Hibernate、JPA和PostgreSQL...以下是我的代码:
User.java
@Entity
@Table(name = "users")
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @NotBlank
    @Size(max = 100)
    @Column(name = "firstName")
    private String name;

    @NotNull
    @NotBlank
    @Size(max = 30)
    @Column(name = "username", unique = true)
    private String username;

    @NotNull
    @NotBlank
    @Size(max = 150)
    @Column(name = "password")
    private String password;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "cityId", nullable = false)
    @JsonIgnore
    private City city;

    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name = "countryId", nullable = false)
    @JsonIgnore
    private Country country;

    // Getters and Setters
    ...
}

UserController.java

@PostMapping("/users/{countryId}/{cityId}")
public User createUser(@PathParam(value = "countryId") Long countryId, @PathParam(value = "cityId") Long cityId,
        @Valid @RequestBody User user) {
    user.setCountry(countryRepository.findById(countryId)
            .orElseThrow(() -> new ResourceNotFoundException("Country not found with id " + countryId)));
    user.setCity(cityRepository.findById(cityId)
            .orElseThrow(() -> new ResourceNotFoundException("City not found with id " + cityId)));
    return userRepository.save(user);
}

UserRepository.java

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    List<User> findByCountryId(Long countryId);

    List<User> findByCityId(Long cityId);
}

我使用Postman进行测试。我尝试使用以下URL(其中1表示countryID,4表示cityId)和Payload创建一个用户:

URL

localhost:8080/users/1/4

有效载荷
{
    "name": "David",
    "username": "david",
    "password": "test",
}

我收到了这个错误...
错误:
{
    "timestamp": "2018-05-07T13:44:03.497+0000",
    "status": 500,
    "error": "Internal Server Error",
    "message": "The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!",
    "path": "/users/1/4"
}

2018-05-07 14:25:40.484错误17964 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet]:在路径为[]的上下文中,对于servlet [dispatcherServlet]的Servlet.service()抛出异常[请求处理失败; 嵌套异常是org.springframework.dao.InvalidDataAccessApiUsageException:给定的id不能为空!; 嵌套异常是java.lang.IllegalArgumentException:给定的id不能为空!],但我不知道如何解决这个问题。

服务器应指向引起问题的代码行。如果不知道原因,可能是 @Valid,因为您创建的用户没有 ID。 - Compass
这是服务器信息给我:"2018-05-07 14:25:40.484 ERROR 17964 --- [io-8080-exec-10] o.a.c.c.C.[.[.[/].[dispatcherServlet] : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is org.springframework.dao.InvalidDataAccessApiUsageException: The given id must not be null!; nested exception is java.lang.IllegalArgumentException: The given id must not be null!] with root cause" - Manu
你的数据库管理器是什么?Oracle 还是 MySQL? - Mạnh Quyết Nguyễn
我的数据库管理器是PostgreSQL。 - Manu
你是否已经获取到了id为1和4的国家和城市的值,并且调试过程中将这两个值都设置到了用户对象中?由于你将实体关系标记为非空,我只是想知道。 - Karthik R
2个回答

5

你应该将PostgreSQL中的id列数据类型设置为SERIAL

@PathParam更改为@PathVariable应该可以解决问题。

你正在使用错误的注释。

编辑

Spring使用注释来执行一些特殊逻辑,从请求URI或请求体中提取值并将其映射到适当的注释参数。

你正在使用错误的注释参数,因此它的值没有被填充。

当您的存储库执行代码以查找null时,将抛出异常。


同样的错误...我认为问题在于URL...但我不知道如何解决。 - Manu
你能提供一个网站或PDF来深入学习或阅读相关内容吗? :) - Manu

-2

不要使用Long,而是使用原始类型long来表示您的ID。

@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;

如果字段不可用,则会使用0启动字段id,从而解决问题。

一般情况下,如果您也可以使用简单的数据类型,尽量避免使用复杂的数据类型。每当您在简单数据类型上使用复杂数据类型时,必须有一个很好的理由。否则,这通常是一种糟糕的做法。


我已经修改了,但是还是出现了相同的错误... 代码: "@Id @GeneratedValue(strategy = GenerationType.IDENTITY) private long id;" - Manu
即使它解决了问题,你认为一个所有主键id = 0的表怎么样? - Mạnh Quyết Nguyễn
@MạnhQuyếtNguyễn 当使用@GeneratedValue进行注释时,它将生成一个新的键,这是标准行为。这是处理此问题的默认方式。 - Herr Derb
@Manu 你确定你已经以干净的方式重新编译了你的项目吗?long类型不能为null。 - Herr Derb
当然可以!但是我遇到了同样的错误,我认为问题在于如何在URL中发送cityId和countryId...这样正确吗?:("/users/{countryId}/{cityId}") --> localhost:8080/users/1/4 - Manu
但是目前数据库服务器中的id列没有正确生成,因此它仍会引发空值。 - Mạnh Quyết Nguyễn

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接