Spring Boot: 推断的类型 ‘S’ 不在其界限内;应该扩展 – saveAndFlush(S)

huangapple go评论69阅读模式
英文:

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类型。有关此类型错误的几个问题已得到解答,涉及到findOne(id)方法,然而,这并不是我的问题的根源,我无法弄清楚如何修复我的代码。

关于我正在使用的方法:

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&lt;Session,Long&gt; {

}

The endpoint in the controller:

@RequestMapping(value = &quot;{id}&quot;, method = RequestMethod.PUT)
    public Session update(@PathVariable Long id, @RequestBody Session session){
        //in original version used in the course use findOne(Id) (deprecated)
        Optional&lt;Session&gt; existingSession = sessionRepository.findById(id);
        //take existing session and copy incoming session data onto it
        BeanUtils.copyProperties(session, existingSession, &quot;session_id&quot;);
        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:

&lt;S extends T&gt; S saveAndFlush(S entity);

and findById in CrudRepository:

Optional&lt;T&gt; 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&lt;Session&gt;. 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 = &quot;{id}&quot;, method = RequestMethod.PUT)
public Session update(@PathVariable Long id, @RequestBody Session session){
    return sessionRepository.findById(id)
        .map(existingSession -&gt; updateSession(existingSession, session))
        .orElseThrow(() -&gt; new IllegalStateException(&quot;No session for id &#39;&quot; + ids + &quot;&#39;&quot;);
}

private Session updateSession(Session existingSession, Session session) {
    BeanUtils.copyProperties(session, existingSession, &quot;session_id&quot;);
    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&lt;Session&gt;`. This is a `Session` wrapped in an `Optional` and thus it isn&#39;t a `Session`. 

The `saveAndFlush` (like `save`) requires a `Session` which, the wrapped `Session` clearly isn&#39;t. What you need to do is unwrap the `Session` from the `Optional` (if it actually exists). 

```java
@RequestMapping(value = &quot;{id}&quot;, method = RequestMethod.PUT)
public Session update(@PathVariable Long id, @RequestBody Session session){
    return sessionRepository.findById(id)
        .map(existingSession -&gt; updateSession(existingSession, session))
        .orElseThrow(() -&gt; new IllegalStateException(&quot;No session for id &#39;&quot; + ids + &quot;&#39;&quot;);
}

private Session updateSession(Session existingSession, Session session) {
    BeanUtils.copyProperties(session, existingSession, &quot;session_id&quot;);
    return sessionRepository.saveAndFlush(existingSession);
}

huangapple
  • 本文由 发表于 2023年2月6日 16:21:00
  • 转载请务必保留本文链接:https://go.coder-hub.com/75358844.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定