【问题标题】:Is it possible JPA/Hibernate use ManyToOne with only parent field?JPA/Hibernate 是否可以仅使用父字段的 ManyToOne?
【发布时间】:2018-08-23 17:51:03
【问题描述】:

我尝试在我的菜单实体之间建立关系,只有一个字段:Parent

我喜欢这样做:

@Entity
@Table
@Getter @Setter
public class ProductCategory extends BaseEntity {
    @Column
    private String name;

    @Column
    private String description;

    @ManyToOne
    @JoinColumn(name = "PARENT_ID")
    private ProductCategory parent;
}

但我得到直接自引用导致循环错误。是否可以只使用一个字段来表示关系?或者我必须将 child 字段定义为 JsonManagedReference?

【问题讨论】:

  • 分享详细的堆栈跟踪。
  • 看起来与杰克逊有关。 “只有一个关系字段”是什么意思?
  • 在多对一中,我们在父类上定义一个字段(按类型集合),然后在子类中定义一个字段作为父类型。是的?但我想在子实体中定义父字段。

标签: hibernate jpa jackson self-reference


【解决方案1】:

我用@OneToMany 做了一次同样的事情,如下所示:

@Entity
@Data
@NoArgsConstructor
@Table(name = "categories")
public class Category {
    @JsonProperty("Id")
    @Id
    private int id;

    @JsonProperty("Code")
    private String code;

    @JsonProperty("Name")
    private String name;

    @JsonProperty("ParentId")
    @Column(name = "parent_id")
    private Integer parent;

    @JsonProperty("NewAdminId")
    private int newAdminId;

    @JsonProperty("VolumetricWeight")
    @Column(name = "volumetricWeight")
    private Float volumetricWeight = 0.0f;

    @JsonProperty("Nodes")
    @OneToMany(
        cascade = CascadeType.ALL,
        fetch = FetchType.EAGER,
        orphanRemoval = true)
    @JoinColumn(name = "parent_id")
    private List<Category> categories;


    public Category(int id, String code, String name, int newAdminId, List<Category> categories) {
        this.id = id;
        this.code = code;
        this.name = name;
        this.newAdminId = newAdminId;
        this.categories = categories;
    }
}

测试证明有效:

@RunWith(SpringRunner.class)
@DataJpaTest
public class CategoryRepositoryTests {

    @Autowired
    private TestEntityManager entityManager;

    @Autowired
    private CategoryRepository categoryRepository;

    @Test
    public void when_findAll_with_specification_returnTopCategory() {

        Category topRoot = CategoryBuilder.aCategory()
                .code("1")
                .id(1)
                .name("test root category")
                .newAdminId(1)
                .parent(null)
                .build();

        Category child = CategoryBuilder.aCategory()
                .code("2")
                .id(2)
                .name("test child category")
                .newAdminId(2)
                .parent(1)
                .build();

        entityManager.persistAndFlush(topRoot);
        entityManager.persistAndFlush(child);

        List<Category> found = categoryRepository.findAll(isTopRoot());

        assertThat(found).hasSize(1);
        assertThat(found.get(0)).isEqualTo(topRoot);
    }
}

【讨论】:

  • 不,伙计,这使得父子之间的无限递归!你必须使用@JsonManagedReference 和@JsonBackReference 来避免这个错误。
  • 好吧,我更新了答案,添加了一些单元测试。实际上,我提供的代码没有出现递归错误。
  • 是的,您的解决方案是正确的!但我将一个字段定义为错误的父(私有类别父;)。谢谢@emre
  • 很高兴为您提供帮助
猜你喜欢
  • 1970-01-01
  • 2012-01-15
  • 2011-12-17
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-02-24
  • 2016-03-08
相关资源
最近更新 更多