【问题标题】:CrudRepository: findAll() stucks in infinite loopCrudRepository:findAll() 陷入无限循环
【发布时间】:2025-12-24 06:40:11
【问题描述】:

我有一个包含两个实体的 OneToMany 数据模型。一台机器包含许多特性。

问题:当我尝试获取数据库的完整数据时,程序陷入了无限循环。查看 JSON 结果 - 数据一直在重复...

[{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":[{"name":null,"description":"CHARACTER2","type":0,"value":0,"machine":{"name":"Neue Machine","description":"Description der neuen machine","characteristics":

等等……

我真的不知道为什么会这样。以编程方式插入数据似乎工作正常! 当前数据由以下代码行产生:

@RequestMapping(value = "/machine", method = RequestMethod.GET)
    Collection<Machine> readMachines(){

        Machine machine = new Machine("Neue Machine", "Description der neuen machine");
        //Set<Characteristic> newCharacter =  new HashSet<Characteristic>(); 
        for(int i = 0; i < 6; i++){
            machine.addCharacteristic(new Characteristic("CHARACTER" + Integer.toString(i),0,0));
        }

        machineRepository.save(machine);

        return (Collection<Machine>) machineRepository.findAll();
    }

问题:无限循环从何而来?

数据库模型

机器:

创建语句:

CREATE TABLE `machine` (
  `id` int(11) NOT NULL AUTO_INCREMENT,
  `name` varchar(45) NOT NULL,
  `description` varchar(45) NOT NULL,
  PRIMARY KEY (`id`)
) ENGINE=InnoDB AUTO_INCREMENT=31 DEFAULT CHARSET=utf8

实体:

@Entity
@Table(name = "characteristic")
public class Characteristic {
    private int characteristic_id; 

    private String name; 

    private String description; 

    private int type; 

    private int value;

    private Machine machine; 

    @ManyToOne
    @JoinColumn(name="machine_id")
    public Machine getMachine(){
        return machine;
    }

    public void setMachine(Machine machine){
        this.machine = machine;
    }

    public Characteristic() {}

    public Characteristic(String description, int type, int value) {
        this.description = description;
        this.type = type;
        this.value = value;
    } 

    public Characteristic(int characteristic_id, String description, int type, int value) {
        this.characteristic_id = characteristic_id;
        this.description = description;
        this.type = type;
        this.value = value;
    } 

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="characteristic_id")
    public int getCharacteristic_Id() {
        return characteristic_id;
    }

    public void setCharacteristic_Id(int characteristic_id) {
        this.characteristic_id = characteristic_id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

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

    @Column(name="description")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    @Column(name="type")
    public int getType() {
        return type;
    }

    public void setType(int type) {
        this.type = type;
    }

    @Column(name="value")
    public int getValue() {
        return value;
    }

    public void setValue(int value) {
        this.value = value;
    }
}

特点:

创建语句:

CREATE TABLE `characteristic` (
  `characteristic_id` int(11) NOT NULL AUTO_INCREMENT,
  `machine_id` int(11) NOT NULL DEFAULT '0',
  `name` varchar(45) DEFAULT NULL,
  `description` varchar(45) DEFAULT NULL,
  `type` int(11) NOT NULL,
  `value` int(11) DEFAULT NULL,
  PRIMARY KEY (`characteristic_id`),
) ENGINE=InnoDB AUTO_INCREMENT=26 DEFAULT CHARSET=latin1

实体:

@Entity
@Table(name = "machine")
public class Machine {
    private int machine_id; 

    private String name;

    private String description; 

    private Set<Characteristic> characteristics;

    @OneToMany(fetch = FetchType.EAGER, mappedBy = "machine", cascade = CascadeType.ALL)
    public Set<Characteristic> getCharacteristics() {
        return characteristics; 
    }

    public void setCharacteristics(Set<Characteristic> characteristics){
        this.characteristics = characteristics;
    }

    public Machine(){}

    public Machine(String name, String description){
        this.name = name;
        this.description = description; 
    }

    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    public int getId() {
        return machine_id;
    }

    public void setId(int machine_id) {
        this.machine_id = machine_id;
    }

    @Column(name="name")
    public String getName() {
        return name;
    }

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

    @Column(name="description")
    public String getDescription() {
        return description;
    }

    public void setDescription(String description) {
        this.description = description;
    }

    public void addCharacteristic(Characteristic characteristic){
        if(this.characteristics == null){
            this.characteristics = new HashSet<Characteristic>();
        }
        characteristic.setMachine(this);
        this.characteristics.add(characteristic);
    }
}

CrudRepository:

public interface MachineRepository extends CrudRepository<Machine, Integer>{}

【问题讨论】:

  • 因为你有一个循环依赖的数据。
  • @RomanC 谢谢你的回答。我理解你的观点,但我没有在我的模型中看到循环依赖。请您详细解释一下好吗?

标签: mysql json spring hibernate entity


【解决方案1】:

在您的代码中,您返回Machine 的集合。此类对Characteristic 具有一对多 依赖关系。 Characteristic 类具有 Many-To-One 依赖关系 om Machine

Machine 对象被序列化时,它正在查看依赖项Characteristic,最后是查看Machyne,依此类推。除非您排除引用同一对象的属性,否则这些循环依赖项不可能序列化。您应该排除 One-To-ManyMany-To-One 属性。

【讨论】:

  • 我明白你的意思。您能否发布一段示例代码?我正在与新错误作斗争。为什么教程经常建议这种循环依赖?
  • 这个答案非常强大,这就是它没有任何代码的原因。如果您怀疑我无法编写代码,您可以浏览我的答案或提出或多或少理智的问题。
  • 我真的不怀疑你的技能
  • 我奖励您的行为以帮助您进一步学习,您也可以对此答案投赞成票,因为如果您的应用程序能够@JsonIgnore 此答案中描述的属性,您就可以忘记循环依赖关系。跨度>