Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/mysql/56.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 在Spring boot中使用post方法保存多个实体时的无限循环_Java_Mysql_Database_Spring Boot_Backend - Fatal编程技术网

Java 在Spring boot中使用post方法保存多个实体时的无限循环

Java 在Spring boot中使用post方法保存多个实体时的无限循环,java,mysql,database,spring-boot,backend,Java,Mysql,Database,Spring Boot,Backend,为了解释我正在处理的问题,我将首先提供代码 往复式控制器 用户控制器 例外情况 问题 因此,当我调用该方法添加配方时,我希望数据库知道有一个新配方,并且新配方链接到添加它的用户。当我删除保存用户实体的部分时,根本不进行映射。但是,当我使用userRepository告诉数据库已经进行了更改(将配方添加到他们的列表中)时,似乎有一个无限的添加新用户的循环。回答您的问题并包括您评论中的最后要求 如果您想打破循环,但有些人想以某种方式保留嵌套对象,我建议编写一个自定义序列化程序,并将导致无休止递归的对

为了解释我正在处理的问题,我将首先提供代码

往复式控制器 用户控制器 例外情况 问题
因此,当我调用该方法添加配方时,我希望数据库知道有一个新配方,并且新配方链接到添加它的用户。当我删除保存用户实体的部分时,根本不进行映射。但是,当我使用userRepository告诉数据库已经进行了更改(将配方添加到他们的列表中)时,似乎有一个无限的添加新用户的循环。

回答您的问题并包括您评论中的最后要求

如果您想打破循环,但有些人想以某种方式保留嵌套对象,我建议编写一个自定义序列化程序,并将导致无休止递归的对象替换为其他字段(在下面的示例中,我使用了author username,它是
String
,而不是
author
对象)

为了重现这个案例,我创建了一个模拟模型,它与您的模型类似

配方

public class Recipe {

    private EvaUser author;
    private String name = "test";
    private String ingridients = "carrots, tomatos";

    public EvaUser getAuthor() {
        return author;
    }

    public void setAuthor(EvaUser author) {
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIngridients() {
        return ingridients;
    }

    public void setIngridients(String ingridients) {
        this.ingridients = ingridients;
    }
}
public class EvaUser {

    private List<Recipe> myRecipes = new ArrayList<>();
    private List<Recipe> favoriteRecipes = new ArrayList<>();
    private String username;

    public List<Recipe> getMyRecipes() {
        return myRecipes;
    }

    public void setMyRecipes(List<Recipe> myRecipes) {
        this.myRecipes = myRecipes;
    }

    public List<Recipe> getFavoriteRecipes() {
        return favoriteRecipes;
    }

    public void setFavoriteRecipes(List<Recipe> favoriteRecipes) {
        this.favoriteRecipes = favoriteRecipes;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}
EvaUser

public class Recipe {

    private EvaUser author;
    private String name = "test";
    private String ingridients = "carrots, tomatos";

    public EvaUser getAuthor() {
        return author;
    }

    public void setAuthor(EvaUser author) {
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIngridients() {
        return ingridients;
    }

    public void setIngridients(String ingridients) {
        this.ingridients = ingridients;
    }
}
public class EvaUser {

    private List<Recipe> myRecipes = new ArrayList<>();
    private List<Recipe> favoriteRecipes = new ArrayList<>();
    private String username;

    public List<Recipe> getMyRecipes() {
        return myRecipes;
    }

    public void setMyRecipes(List<Recipe> myRecipes) {
        this.myRecipes = myRecipes;
    }

    public List<Recipe> getFavoriteRecipes() {
        return favoriteRecipes;
    }

    public void setFavoriteRecipes(List<Recipe> favoriteRecipes) {
        this.favoriteRecipes = favoriteRecipes;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}
来自控制器的
EvaUser
的JSON响应主体(前一个是
StackOverflowerError
):


可能重复:@MehrajMalik这个问题和答案似乎有点过时了。我觉得这个对我没什么帮助。无论如何,谢谢。所有的技巧对当前任务也有效。这是由保存操作引起的吗?在我看来,Jackson似乎正试图在你的
getAllUsers()
中序列化你的
EvaUser
,因为它引用了
Recipe
,并且
Recipe
引用了
EvaUser
,它无法正确地序列化它,并最终进入映射该链的无限循环。通过添加
@JsonIgnore
来打破该链的@MehrajMalik提供的答案实际上是一个正确的解决方案,并且没有过时。只是偶然发现了答案。我确实犯了一个错误,使用author作为一个对象,其中也包含recipe,导致了一个循环。非常感谢。
Failed to write HTTP message: 
org.springframework.http.converter.HttpMessageNotWritableException: Could 
not write content: Infinite recursion
public class Recipe {

    private EvaUser author;
    private String name = "test";
    private String ingridients = "carrots, tomatos";

    public EvaUser getAuthor() {
        return author;
    }

    public void setAuthor(EvaUser author) {
        this.author = author;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public String getIngridients() {
        return ingridients;
    }

    public void setIngridients(String ingridients) {
        this.ingridients = ingridients;
    }
}
public class EvaUser {

    private List<Recipe> myRecipes = new ArrayList<>();
    private List<Recipe> favoriteRecipes = new ArrayList<>();
    private String username;

    public List<Recipe> getMyRecipes() {
        return myRecipes;
    }

    public void setMyRecipes(List<Recipe> myRecipes) {
        this.myRecipes = myRecipes;
    }

    public List<Recipe> getFavoriteRecipes() {
        return favoriteRecipes;
    }

    public void setFavoriteRecipes(List<Recipe> favoriteRecipes) {
        this.favoriteRecipes = favoriteRecipes;
    }

    public String getUsername() {
        return username;
    }

    public void setUsername(String username) {
        this.username = username;
    }
}
import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.databind.SerializerProvider;
import com.fasterxml.jackson.databind.ser.std.StdSerializer;

import java.io.IOException;
import java.util.Optional;

public class RecipeSerializer extends StdSerializer<Recipe> {

    protected RecipeSerializer() {
        this(null);
    }

    protected RecipeSerializer(Class<Recipe> t) {
        super(t);
    }

    @Override
    public void serialize(Recipe recipe, JsonGenerator gen, SerializerProvider provider) throws IOException {
        gen.writeStartObject();

        gen.writeStringField("name", recipe.getName());
        gen.writeStringField("author", Optional.ofNullable(recipe.getAuthor().getUsername()).orElse("null"));
        gen.writeStringField("ingridients", recipe.getIngridients());

        gen.writeEndObject();
    }
}
@JsonSerialize(using = RecipeSerializer.class)
public class Recipe {
    // model entity
}
{
    "myRecipes": [
        {
            "name": "soup",
            "author": "user1",
            "ingridients": "carrots, tomatos"
        },
        {
            "name": "steak",
            "author": "user1",
            "ingridients": "meat, salt"
        }
    ],
    "favoriteRecipes": [
        {
            "name": "soup",
            "author": "user1",
            "ingridients": "carrots, tomatos"
        },
        {
            "name": "steak",
            "author": "user1",
            "ingridients": "meat, salt"
        }
    ],
    "username": "user1"
}