是否可以 JPA/Hibernate 仅对父字段使用 ManyToOne?

Is it possible JPA/Hibernate use ManyToOne with only parent field?

我尝试在我的 Menus 实体之间建立只有一个字段的关系: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?

我用@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);
    }
}