簡體   English   中英

在 JpaRepository function 'findby...' 中使用我自己的值名稱創建 bean 時出錯

[英]Error creating bean with my own value name in JpaRepository function 'findby...'

彈簧啟動 hibernate ORM

首先,我使用的是springboot 2.5.12版本,我嘗試在我的項目中實現登錄function。

我在為登錄創建的用戶層中的用戶實體變量中將 email 和密碼聲明為“uEmail”和“uPassword”。 寫好代碼建好后,看到無法創建bean的錯誤。 看的時候發現JpaRepository庫中的findByEmailAndPassword function 報錯。

報錯說明如下:

Error creating bean with name 'userController': 
Unsatisfied dependency expressed through field 'userService'; 
nested exception is org.springframework.beans.factory.UnsatisfiedDependencyException: 
Error creating bean with name 'userService': 
Unsatisfied dependency expressed through field 'userRepository'; 
nested exception is org.springframework.beans.factory.BeanCreationException: 
Error creating bean with name 'userRepository' defined in com.lululala.peopleofwork.persistance.UserRepository defined in @EnableJpaRepositories declared on JpaRepositoriesRegistrar.EnableJpaRepositoriesConfiguration: 
Invocation of init method failed; nested exception is org.springframework.data.repository.query.QueryCreationException: Could not create query for public abstract com.lululala.peopleofwork.model.UserEntity com.lululala.peopleofwork.persistance.UserRepository.findByEmailAndPassword(java.lang.String,java.lang.String)! 
Reason: Failed to create query for method public abstract com.lululala.peopleofwork.model.UserEntity com.lululala.peopleofwork.persistance.UserRepository.findByEmailAndPassword(java.lang.String,java.lang.String)! 
No property email found for type UserEntity! Did you mean 'uEmail','UEmail'?; 
nested exception is java.lang.IllegalArgumentException: 
Failed to create query for method public abstract com.lululala.peopleofwork.model.UserEntity com.lululala.peopleofwork.persistance.UserRepository.findByEmailAndPassword(java.lang.String,java.lang.String)! 
No property email found for type UserEntity! Did you mean 'uEmail','UEmail'?

一開始我在想是不是變量寫成CamelCase有問題,於是把變量改成SnakeCase,結果還是一樣的錯誤。

下面是我的代碼。

用戶實體.java

@Data
@Entity
@Builder
@NoArgsConstructor
@AllArgsConstructor
@Table(uniqueConstraints = {@UniqueConstraint(columnNames = "uEmail")})

public class UserEntity {
    @Id
    @GeneratedValue(generator="system-uuid")
    @GenericGenerator(name = "system-uuid", strategy = "uuid")
    private String id; // Unique id granted to user
    
    @Column(nullable = false)
    private String uName; // User name

    @Column(nullable = false)
    private String uEmail; // User email(Id)
    
    @Column(nullable = false)
    private String uPassword; // User password
    
}

用戶服務.java

@Slf4j
@Service
public class UserService {
    
    @Autowired
    private UserRepository userRepository;
    
    public UserEntity create(final UserEntity userEntity) {
        
        if(userEntity == null || userEntity.getUEmail() == null) {
            throw new RuntimeException("Invalid arguments");
        }
        
        final String email = userEntity.getUEmail();
        if(userRepository.existsByEmail(email)) {
            log.warn("Email already exists {}", email);
            throw new RuntimeException("Email already exists");
        }
        
        return userRepository.save(userEntity);
    }
    
    public UserEntity getByCredentials(final String uEmail, final String uPassword) {
        return userRepository.findByEmailAndPassword(uEmail, uPassword);
    }
}

UserRepository.java

@Repository
public interface UserRepository extends JpaRepository<UserEntity, String> {
    UserEntity findByEmail(String uEmail);
    Boolean existsByEmail(String uEmail);
    UserEntity findByEmailAndPassword(String uEmail, String uPassword);
}

UserController.java

@Slf4j
@RestController
@RequestMapping("/auth")
public class UserController {
        
    @Autowired
    private UserService userService;
    
    //skip signup method 

    @PostMapping("/signin")
    public ResponseEntity<?> authenticate(@RequestBody UserDTO userDTO){
        UserEntity user = userService.getByCredentials(
                userDTO.getUEmail(),
                userDTO.getUPassword());
        
        if(user != null) {
            final UserDTO responseUserDTO = UserDTO.builder()
                    .uEmail(user.getUEmail())
                    .id(user.getId())
                    .build();
            
            return ResponseEntity.ok().body(responseUserDTO);
        } else {
            ResponseDTO responseDTO = ResponseDTO.builder()
                    .error("Login failed.")
                    .build();
            
            return ResponseEntity.badRequest().body(responseDTO);
        }
    }
}

用戶DTO.java

@Data
@Builder
@NoArgsConstructor
@AllArgsConstructor
public class UserDTO {
    private String token;
    private String uEmail;
    private String uName;
    private String uPassword;
    private String id;
}

我也在hibernate ORM找過命名攻略,也沒有得到明確的答復。 下面是我找的網站。

https://docs.jboss.org/hibernate/orm/5.3/userguide/html_single/Hibernate_User_Guide.html#naming

https://www.jpa-buddy.com/blog/hibernate-naming-strategies-jpa-specification-vs-springboot-opinionation/

https://docs.jboss.org/hibernate/orm/5.4/javadocs/org/hibernate/boot/model/naming/Identifier.html

最終,我將變量名改為'email'和'password'並解決了它,但無論如何,UserRepository所做的是編寫查詢,變量名由編寫代碼的人自行決定,所以我想知道為什么會有是一個錯誤。

任何幫助表示贊賞!

這似乎是問題所在:

UserEntity findByEmailAndPassword(String uEmail, String uPassword);

由於該方法是 findByEmailAndPassword,JPA 試圖將查詢創建為: select email,password from User ,同時它正在 UserEntity 中查找屬性emailpassword

由於您已將屬性名稱定義為uEmail ,因此它會拋出指示性錯誤:

No property email found for type UserEntity! Did you mean 'uEmail','UEmail'?; 

顯而易見的解決方案是將存儲庫方法重命名為:

UserEntity findByUEmailAndUPassword(String uEmail, String uPassword);

總之,存儲庫方法應與實體屬性名稱相匹配。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM