调用/users/register接口时,JPA保存User出现实体未识别错误
问题:JPA保存实体时抛出"XXX is not an entity"错误
我通过POST请求调用/users/register接口,请求体如下:
{ "username": "daniel", "email": "email@yahoo.com", "password": "something" }
调用后触发500内部服务器错误,核心错误信息:
{ "timestamp": "2023-03-08T05:40:40.215+00:00", "status": 500, "error": "Internal Server Error", "message": "com.youngahn.RobinhoodAPI.controllers.UserController$1 is not an entity", "path": "/users/register" }
相关代码如下:
User实体类
package com.youngahn.RobinhoodAPI.entity; import jakarta.persistence.*; import jakarta.validation.constraints.NotBlank; import lombok.Data; import java.math.BigDecimal; import java.util.HashSet; import java.util.Set; @Entity @Table(name = "users") @Data public class User { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @NotBlank private String username; @NotBlank private String email; @NotBlank private String password; private BigDecimal funds = new BigDecimal("0.00"); @OneToMany(fetch = FetchType.LAZY, mappedBy = "user") public Set<UserStock> userStocks = new HashSet<>(); }
UserController控制器类
package com.youngahn.RobinhoodAPI.controllers; import com.youngahn.RobinhoodAPI.dtos.LoginRequestDto; import com.youngahn.RobinhoodAPI.dtos.RegisterRequestDto; import com.youngahn.RobinhoodAPI.entity.User; import com.youngahn.RobinhoodAPI.repository.UserRepository; import jakarta.validation.Valid; import org.springframework.beans.factory.annotation.Autowired; import org.springframework.http.ResponseEntity; import org.springframework.web.bind.annotation.*; @RestController @RequestMapping("/users") @CrossOrigin(origins = "*") public class UserController { private UserRepository userRepository; @Autowired public UserController(UserRepository userRepository) { this.userRepository = userRepository; } @PostMapping("/signin") public ResponseEntity<?> getUser(@RequestBody LoginRequestDto loginRequestDto) { return ResponseEntity.ok(loginRequestDto); } @PostMapping("/register") public ResponseEntity<?> createUser(@Valid @RequestBody RegisterRequestDto registerRequestDto) { User user = new User() {{ setUsername(registerRequestDto.getUsername()); setEmail(registerRequestDto.getEmail()); setPassword(registerRequestDto.getPassword()); }}; userRepository.save(user); return ResponseEntity.ok(registerRequestDto); } }
UserRepository仓库类
package com.youngahn.RobinhoodAPI.repository; import com.youngahn.RobinhoodAPI.entity.User; import org.springframework.data.jpa.repository.JpaRepository; import org.springframework.stereotype.Repository; @Repository public interface UserRepository extends JpaRepository<User, Long> { }
问题原因
你用了**双重初始化(匿名内部类)**的方式创建User对象:
User user = new User() {{ setUsername(registerRequestDto.getUsername()); // ... }};
这种写法会生成一个User的匿名子类(也就是错误里的UserController$1),但JPA只能识别标注了@Entity的原始实体类,无法识别这个动态生成的子类,因此抛出"not an entity"错误。
修复方案
换成常规的对象初始化方式即可:
@PostMapping("/register") public ResponseEntity<?> createUser(@Valid @RequestBody RegisterRequestDto registerRequestDto) { User user = new User(); user.setUsername(registerRequestDto.getUsername()); user.setEmail(registerRequestDto.getEmail()); user.setPassword(registerRequestDto.getPassword()); userRepository.save(user); return ResponseEntity.ok(registerRequestDto); }
如果想让代码更简洁,可以给User类加上Lombok的@Builder注解:
- 修改User实体类:
@Entity @Table(name = "users") @Data @Builder public class User { // 原有代码不变 }
- 在Controller中使用Builder创建对象:
User user = User.builder() .username(registerRequestDto.getUsername()) .email(registerRequestDto.getEmail()) .password(registerRequestDto.getPassword()) .build();
额外提醒
- 密码不要明文存储,建议用BCrypt等加密工具处理后再保存。
- 可以添加用户名/邮箱的唯一性校验,避免重复注册。
内容的提问来源于stack exchange,提问作者Danii
相关产品推荐
相关产品推荐

