簡體   English   中英

獲取嵌套實體數據導致stackoverflow錯誤

[英]Getting nested entity data resulting in stackoverflow error

我在2表用戶和笑話之間有很多關系。 它們由連接表fav_joke連接,該表保存這些表中的id值。 根據我的設置,當II從這些表中插入和刪除時,它似乎可以正常工作。

問題是當我嘗試查詢User表以獲取所有關聯的笑話時。 再次工作正常,但以某種初始形式重復執行此操作,最終導致StackOverflow錯誤。 請參閱圖像以查看響應。 如您所見,我在玩笑中找到了一個用戶,該笑話又有自己的笑話,又有自己的用戶,而且還在不斷發展……

問題快照

我期望在進行此查詢時在用戶下僅具有關聯的笑話,在這種情況下應為2,僅此而已。 我認為這與我在Joke實體中具有@ManyToMany關系注釋有關,但是我相信我需要這樣做。 請指教。 謝謝。

實體

@Getter
@Setter
@NoArgsConstructor
@Entity
public class User {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    long memberId;

    @ManyToMany
    @JoinTable(
        name = "fav_joke",
        joinColumns = @JoinColumn(name = "memberId"),
        inverseJoinColumns = @JoinColumn(name = "id")
    )
    private Set<Joke> jokes;
}  

@Getter
@Setter
@NoArgsConstructor
@Entity
@Table(name = "joke")
public class Joke {

    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private long id;

    private String question;
    private String answer;
    private boolean isFav;

    @ManyToMany(mappedBy = "jokes")
    private Set<User> users;
}

儲存庫

@Repository
public interface UserRepository extends JpaRepository<User, Long> {
    User getUserByMemberId(long memberId);
}

@Repository
public interface JokeRepository extends JpaRepository<Joke, Long> {
    @Query("select j from Joke j where j.id =:id")
    Joke getJokeById(long id);
}

控制器-此調用是將堆棧溢出的調用。

@GetMapping("/get/fav/member_id/{memberId}")
public Set<Joke> getAllFavJokes(@PathVariable long memberId){
    User user = userRepository.getUserByMemberId(memberId);
    return user.getJokes();
}

我認為這無關緊要。 只是添加它以防萬一。 這樣做將填充由於多對多映射而在運行中創建的fav_joke表。

@GetMapping("/fav/joke_id/{id}/member_id/{memberId}/isFav/{isFav}")
    public String toggleFavJoke(@PathVariable long id, @PathVariable long memberId, @PathVariable boolean isFav){
        Joke joke = jokeRepository.getJokeById(id);
        User user = userRepository.findById(memberId).orElse(null);

        if(user != null && joke != null){
            if(user.getJokes() != null){
                if(isFav){
                    user.getJokes().remove(joke);
                }else {
                    user.getJokes().add(joke);
                }
            }else {
                if(!isFav){
                    user.setJokes(Stream.of(joke).collect(Collectors.toSet()));
                }
            }
            userRepository.save(user);
            return "Fav toggled successfully";
        }
        return "Unable to add fav. Invalid user or joke";
    }

當前表內的信息如下:(笑話表有1k +行)

表數據

更新

根據評論中的建議添加了@@ JsonIdentityInfoannotation。 現在已經解決了堆棧溢出問題,但是信息的添加方式不正確。

這是我得到的JSON格式。

[{
    "id": 5,
    "question": "What is a gas station's favorite type of shoe?",
    "answer": "Pumps.",
    "users": [{
        "memberId": 1,
        "jokes": [5, {
            "id": 7,
            "question": "What kind of place should you never take a dog?",
            "answer": "To the Flea Market.",
            "users": [1],
            "fav": false
        }, {
            "id": 8,
            "question": "What do you call a cow in an earthquake?",
            "answer": "A milkshake!",
            "users": [1],
            "fav": false
        }, {
            "id": 6,
            "question": "Why was 6 afraid of 7?",
            "answer": "Because 7 8 9!",
            "users": [1],
            "fav": false
        }, {
            "id": 4,
            "question": "Why was Dracula put in jail?",
            "answer": "He tried to rob a blood bank.",
            "users": [1],
            "fav": false
        }]
    }],
    "fav": false
}, 7, 8, 6, 4]

奇怪的是,只有第一個笑話停留在最前面,其余的笑話一直被附加到上面的用戶列表中。

我期待以下內容(並計划排除內部用戶數據)。

[
    {
        "id": 6,
        "question": "J1 What is a gas station's favorite type of shoe?",
        "answer": "Pumps.",
        "users": [{
            "memberId": 1,
            "jokes": [5]
        }],
        "fav": false
    },
    {
        "id": 6,
        "question": "J2 What is a gas station's favorite type of shoe?",
        "answer": "Pumps.",
        "users": [{
            "memberId": 1,
            "jokes": [6]
        }],
        "fav": false
    },
    {
        "id": 7,
        "question": "J3 What is a gas station's favorite type of shoe?",
        "answer": "Pumps.",
        "users": [{
            "memberId": 1,
            "jokes": [7]
        }],
        "fav": false
    }
] 

您可以使用@JsonIgnoreProperties中斷周期:

public class Joke {

    @JsonIgnoreProperties("jokes")
    public Set<User> getUsers(){
        return this.users;
    }    
}  

如果獲得User,則可能會發生相同的問題,因此您可能還需要中斷User的周期:

public class User {

    @JsonIgnoreProperties("users")
    public Set<Joke> getJokes(){
        return this.jokes;
    }    
}  

暫無
暫無

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

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