我正在使用 Spring Data JPA 和 Hibernate 映射開發 Spring Boot 專案。在我的存盤庫類中,我使用按方法名稱查詢的方法,我有以下問題。我有這個用戶物體類:
@Entity
@Table(name = "portal_user")
@Getter
@Setter
public class User implements Serializable {
private static final long serialVersionUID = 5062673109048808267L;
@Id
@Column(name = "id")
@GeneratedValue(strategy=GenerationType.IDENTITY)
private Integer id;
@Column(name = "first_name")
@NotNull(message = "{NotNull.User.firstName.Validation}")
private String firstName;
@Column(name = "middle_name")
private String middleName;
@Column(name = "surname")
@NotNull(message = "{NotNull.User.surname.Validation}")
private String surname;
@Column(name = "sex")
@NotNull(message = "{NotNull.User.sex.Validation}")
private char sex;
@Column(name = "birthdate")
@NotNull(message = "{NotNull.User.birthdate.Validation}")
private Date birthdate;
@Column(name = "tax_code")
@NotNull(message = "{NotNull.User.taxCode.Validation}")
private String taxCode;
@Column(name = "e_mail")
@NotNull(message = "{NotNull.User.email.Validation}")
private String email;
@Column(name = "pswd")
@NotNull(message = "{NotNull.User.pswd.Validation}")
private String pswd;
@Column(name = "contact_number")
@NotNull(message = "{NotNull.User.contactNumber.Validation}")
private String contactNumber;
@Temporal(TemporalType.DATE)
@Column(name = "created_at")
private Date createdAt;
@Column(name = "is_active")
private boolean is_active;
@OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy = "user", orphanRemoval = true)
@JsonManagedReference
private Set<Address> addressesList = new HashSet<>();
@ManyToMany(cascade = { CascadeType.MERGE })
@JoinTable(
name = "portal_user_user_type",
joinColumns = { @JoinColumn(name = "portal_user_id_fk") },
inverseJoinColumns = { @JoinColumn(name = "user_type_id_fk") }
)
Set<UserType> userTypes;
@ManyToOne(fetch = FetchType.EAGER)
@JsonProperty("subagent")
private User parent;
public User() {
super();
// TODO Auto-generated constructor stub
}
public User(String firstName, String middleName, String surname, char sex, Date birthdate, String taxCode,
String email, String pswd, String contactNumber, Date createdAt, boolean is_active) {
super();
this.firstName = firstName;
this.middleName = middleName;
this.surname = surname;
this.sex = sex;
this.birthdate = birthdate;
this.taxCode = taxCode;
this.email = email;
this.pswd = pswd;
this.contactNumber = contactNumber;
this.createdAt = createdAt;
this.is_active = is_active;
}
}
然后我有這個存盤庫介面:
public interface UsersRepository extends JpaRepository<User, Integer> {
/**
* Retrieve an user by its e-mail address:
* @param email is the e-mail of the user
* @return the user related to the specified e-mail
*/
User findByemail(String email);
/**
* Retrieve the list of users belonging to a specific user type
* @param typeName is the name of the user type
* @return the list of users belonging to a specific user type
*/
List<User> findByUserTypes_TypeName(String typeName);
/**
* Retrieve the list of users children of an user.
* Generally used to retrieve the client users of a specific sub-agent user
* @param id is the id of the parent user
* @return the list of children of a specific user (generally used to retrieve the client users of a specific sub-agent user)
*/
List<User> findByParent_Id(Integer id);
/**
* Retrieve an user starting from is id
* @param id of the user which you want to retrieve
* @return the retrieved object
*/
Optional<User> findById(Integer id);
}
我的疑問是最后一種方法(旨在通過其自己的 id 欄位值檢索用戶物件,這個:
Optional<User> findById(Integer id);
最初我試圖將其簡單地定義為:
User findById(Integer id);
但是以這種方式 Eclipse\STS 會給我以下錯誤:
Multiple markers at this line
- implements org.springframework.data.repository.CrudRepository<com.easydefi.users.entity.User,java.lang.Integer>.
findById
- The return type is incompatible with CrudRepository<User,Integer>.findById(Integer)
- The return type is incompatible with CrudRepository<User,Integer>.findById(Integer)
為什么會出現這個錯誤?為什么 Eclipse 強迫我Optional<User>作為回傳型別回傳?這是什么可選的?為什么在findByemail() 中允許我回傳一個簡單的用戶型別?
uj5u.com熱心網友回復:
正如您在擴展介面的JavaDoc中看到的那樣,已經有一個具有相同簽名的方法。CrudRepositoryJpaRepositoryfindById
Java 重寫規則不允許您擁有具有相同名稱和引數的方法以及與父類定義不一致的回傳型別(在本例中為Optional<User>)。
如果您以某種方式更改方法名稱,Spring Data JPA 將能夠使用普通參考。在這種情況下,null如果未找到物體,將回傳。但是,對于您的情況,您應該放棄您的findById方法。
uj5u.com熱心網友回復:
您的存盤庫擴展了 JpaRepository。JpaRepository 擴展了擴展 CrudRepository 的 PagingAndSortingRepository。CrudRepository 有方法:Optional<T> findById(ID var1);.
https://docs.spring.io/spring-data/jpa/docs/current/api/org/springframework/data/jpa/repository/JpaRepository.html
當您使用此簽名定義方法時,您將覆寫 CrudRepository 方法。但是,如果您為存盤庫中創建的此方法定義不同的回傳型別,您的代碼將無法編譯。
Optional 是在 Java 8 中創建的,在 resume 中,用于表示方法的回傳資料可能為 null。在這些場景中使用 Optional 是一個很好的做法。 https://docs.oracle.com/javase/8/docs/api/java/util/Optional.html
關于您提到的另一種方法,它們只是您可以根據需要創建的 UsersRepository 的方法。
uj5u.com熱心網友回復:
Alexy 和 Raul 已經很好地解釋了為什么這不起作用。但是為避免這個問題提供的選擇是相當有限的。以下是您擁有的最相關的選項:
省略您的
findById方法,只使用CrudRepository. 有效,但似乎你不想要,Optional所以這并不令人滿意。您可以通過使用替代方法來修改方法名稱
find,例如search或query。有關可能使用的單詞串列,請參閱https://docs.spring.io/spring-data/jpa/docs/current/reference/html/#repository-query-keywords。您還可以在
find和之間添加任何內容By。findUserById也可以。您可以決定不繼承自
CrudRepository. 這當然也將洗掉所有其他方法CrudRepository。但是,如果您將他們的宣告復制到您的存盤庫介面中,則將獲得正確的實作。您也可以使用此變體來修剪您可能不想在存盤庫中包含的方法。
轉載請註明出處,本文鏈接:https://www.uj5u.com/caozuo/408189.html
標籤:
