难以映射 1 parent class 与 3 child classes 的 OneToOne 关系

Having difficulties mapping OneToOne relation of 1 parent class with 3 child classes

我有一个 parent class 叫 FoodInfo,还有 3 个 child class 叫 IngredientTagMiscellaneousDataFoodInfo 和每个 class 之间的关系是 OneToOne.

目前,我是这样定义 classes:

食品信息:

@Entity
@Table(name="food")
public class FoodInfo {
    
    @Id
    @Column(name="code")
    private Long code;
    
    @OneToOne(mappedBy = "foodInfo", cascade = CascadeType.ALL)
    private Tag tag;
    
    @OneToOne(mappedBy = "foodInfo", cascade = CascadeType.ALL)
    private Ingredient ingredient;
    
    @OneToOne(mappedBy = "foodInfo", cascade = CascadeType.ALL)
    private MiscellaneousData misc;

    //And the getters and setters for all attributes including:

    public Ingredient getIngredient() {
        return ingredient;
    }

    public MiscellaneousData getMisc() {
        return misc;
    }

    public String getProduct_name() {
        return product_name;
    }
    
    public void setTag(Tag tag) {
        this.tag = tag;
    }

    public void setIngredient(Ingredient ingredient) {
        this.ingredient = ingredient;
    }

    public void setMisc(MiscellaneousData misc) {
        this.misc = misc;
    }
}

成分class:

@Entity
@Table(name="ingredient")
public class Ingredient {
    
    @Id
    @Column(name = "id")
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    
    @JoinColumn(name = "code")
    private FoodInfo foodInfo;

    public FoodInfo getFoodInfo() {
        return foodInfo;
    }
    public void setFoodInfo(FoodInfo foodInfo) {
        this.foodInfo = foodInfo;
    }
}

另外两个child class和Ingredient一样。

最后,插入我喜欢的所有数据:

FoodInfo food = new FoodInfo();
Ingredient ing = new Ingredient();
MiscellaneousData misc = new MiscellaneousData();
Tag tag = new Tag();

//And after setting all their attributes...

food.setTag(tag);
food.setMisc(misc);
food.setIngredient(ing);

tag.setFoodInfo(food);
misc.setFoodInfo(food);
ing.setFoodInfo(food);
        
foodRepository.save(food);

现在,当我尝试 运行 程序时,出现错误:

org.springframework.beans.factory.BeanCreationException: Error creating bean with name  'entityManagerFactory' defined in class path resource  
[org/springframework/boot/autoconfigure/orm/jpa/HibernateJpaConfiguration.class]:

Invocation of init  method failed; nested exception is org.hibernate.AnnotationException: Referenced property not a  (One|Many)ToOne: com.guillermo.off.model.Ingredient.foodInfo in mappedBy of  com.guillermo.off.model.FoodInfo.ingredient 

............

Caused by: org.hibernate.AnnotationException: Referenced property not a (One|Many)ToOne: com.guillermo.off.model.Ingredient.foodInfo in mappedBy of com.guillermo.off.model.FoodInfo.ingredient

在之前的尝试中,我以不同的方式使用注释设法将数据插入数据库,但是当我尝试获取所有这些数据时,程序陷入了无限循环。

任何帮助将不胜感激!提前致谢!!

编辑:

按照@Hülya 的建议进行操作后,数据库中的信息似乎是正确的:

但是在请求信息时,我 运行 进入了一个看起来无限循环的地方。

我请求数据的代码是:

@GetMapping("/food")
public List<FoodInfo> findFood(HttpServletResponse response) {
    List<FoodInfo> food = foodService.findAll();
    return food;
}

...而在控制台中,我只能看到以下内容一千次:

at com.fasterxml.jackson.databind.ser.BeanPropertyWriter.serializeAsField(BeanPropertyWriter.java:728) ~[jackson-databind-2.11.4.jar:2.11.4] at com.fasterxml.jackson.databind.ser.std.BeanSerializerBase.serializeFields(BeanSerializerBase.java:755) ~[jackson-databind-2.11.4.jar:2.11.4]

@OneToOne 父子端都应该使用注释来创建双向一对一映射。

如错误所述:Referenced property not a (One|Many)ToOne Ingredient 侧没有映射。

您应该为 foodInfo 字段指定实体关联 @OneToOne:

@Entity
@Table(name="ingredient")
public class Ingredient {
    // ...
    @OneToOne
    @JoinColumn(name = "code")
    private FoodInfo foodInfo;
}

com.fasterxml.jackson.databind 异常的更新:

用jackson序列化双向关系时,循环依赖导致死循环。要打破循环,您应该添加 @JsonManagedReference@JsonBackReference 注释:

食品信息class:

@Entity
@Table(name="food")
public class FoodInfo {
    // ...
    @OneToOne(mappedBy = "foodInfo", cascade = CascadeType.ALL)
    @JsonManagedReference
    private Ingredient ingredient;
}

成分class:

@Entity
@Table(name="ingredient")
public class Ingredient {
    //...
    @OneToOne
    @JoinColumn(name = "code")
    @JsonBackReference
    private FoodInfo foodInfo;
}