英文:
Spring Boot: Inferred type 'S' for type parameter 'S' is not within its bound; should extend - saveAndFlush(S)
问题
我刚刚开始了一个使用较旧版本(2.19)的Spring Boot课程,而我使用的是3.0.2。以下是代码的代表部分:
我的自定义存储库:
public interface SessionRepository extends JpaRepository<Session, Long> {
}
控制器中的端点:
@RequestMapping(value = "{id}", method = RequestMethod.PUT)
public Session update(@PathVariable Long id, @RequestBody Session session) {
//在课程中使用的原始版本中使用findOne(Id)(已弃用)
Optional<Session> existingSession = sessionRepository.findById(id);
//获取现有会话并将传入的会话数据复制到其中
BeanUtils.copyProperties(session, existingSession, "session_id");
return sessionRepository.saveAndFlush(existingSession);
}
一切都很顺利,直到saveAndFlush,它给我了上面提到的错误。
似乎在最新的Spring Boot 3.0.2中,findOne()已被弃用,而我必须使用findById()并返回Optional
关于我正在使用的方法:
JpaRepository中的saveAndFlush:
<S extends T> S saveAndFlush(S entity);
CrudRepository中的findById:
Optional<T> findById(ID id);
我了解问题在于在我的情况下,S和T都是相同的Session对象 - 因此错误告诉我要扩展Session模型。Session是T,我的自定义存储库(SessionRepository)中的对象,但它也是S,我从saveAndFlush()中传入和返回的对象。相反,我应该传递和返回从我的Session对象扩展的东西(S extends T)。我不确定如何扩展这一点,而不会破坏我的代码中的其他内容,我感觉我应该覆盖一些东西,正如其他人建议的那样,但我不确定在哪里做这个。
英文:
I just started a Spring Boot course which uses an older version (2.19) while I use 3.0.2. Here is a representative part of the code first:
My custom repository:
public interface SessionRepository extends JpaRepository<Session,Long> {
}
The endpoint in the controller:
@RequestMapping(value = "{id}", method = RequestMethod.PUT)
public Session update(@PathVariable Long id, @RequestBody Session session){
//in original version used in the course use findOne(Id) (deprecated)
Optional<Session> existingSession = sessionRepository.findById(id);
//take existing session and copy incoming session data onto it
BeanUtils.copyProperties(session, existingSession, "session_id");
return sessionRepository.saveAndFlush(existingSession);
}
All is fine until saveAndFlush, which gives me the above mentioned error.
It appears with the latest Spring Boot 3.0.2 findOne() has been deprecated and instead I have to use findById() and return an Optional<Session> type. Several questions on this type of error have been answered referring to findOne(id) method, however, this isn't the source of my problem and I can't figure out how to fix my code..
About the methods I'm using:
saveAndFlush in JpaRepository:
<S extends T> S saveAndFlush(S entity);
and findById in CrudRepository:
Optional<T> findById(ID id);
I understand the problem is that in my case both S and T are the same Session object - hence the error is telling me to extend the Session model.
Session is T, the object in my custom repository (SessionRepository), but it is also S, the object I pass in and return from saveAndFlush(). Instead, I should be passing and returning something that is extended from my Session object (S extends T0. I am not sure how to extend this without breaking everything else in my code, I feel instead I should overwrite something, as other have suggested, but I am not sure where to do that
答案1
得分: 3
代码部分不需要翻译,以下是已经翻译好的部分:
"The problem is your code. The findById
as you mention yourself and from the documentation returns an Optional<Session>
. This is a Session
wrapped in an Optional
and thus it isn't a Session
.
The saveAndFlush
(like save
) requires a Session
which, the wrapped Session
clearly isn't. What you need to do is unwrap the Session
from the Optional
(if it actually exists).
@RequestMapping(value = "{id}", method = RequestMethod.PUT)
public Session update(@PathVariable Long id, @RequestBody Session session){
return sessionRepository.findById(id)
.map(existingSession -> updateSession(existingSession, session))
.orElseThrow(() -> new IllegalStateException("No session for id '" + ids + "'");
}
private Session updateSession(Session existingSession, Session session) {
BeanUtils.copyProperties(session, existingSession, "session_id");
return sessionRepository.saveAndFlush(existingSession);
}
```"
<details>
<summary>英文:</summary>
The problem is your code. The `findById` as you mention yourself and from the documentation returns an `Optional<Session>`. This is a `Session` wrapped in an `Optional` and thus it isn't a `Session`.
The `saveAndFlush` (like `save`) requires a `Session` which, the wrapped `Session` clearly isn't. What you need to do is unwrap the `Session` from the `Optional` (if it actually exists).
```java
@RequestMapping(value = "{id}", method = RequestMethod.PUT)
public Session update(@PathVariable Long id, @RequestBody Session session){
return sessionRepository.findById(id)
.map(existingSession -> updateSession(existingSession, session))
.orElseThrow(() -> new IllegalStateException("No session for id '" + ids + "'");
}
private Session updateSession(Session existingSession, Session session) {
BeanUtils.copyProperties(session, existingSession, "session_id");
return sessionRepository.saveAndFlush(existingSession);
}
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论