Spring boot Rest创建一个可以引用或不引用其他类别的类别

Spring boot Rest创建一个可以引用或不引用其他类别的类别,spring,hibernate,rest,spring-boot,Spring,Hibernate,Rest,Spring Boot,我有一个实体类 public class CategoryEntity implements Serializable { @Getter(AccessLevel.NONE) @Setter(AccessLevel.NONE) private static final long serialVersionUID = 1L; @Id @GeneratedValue(strategy= GenerationType.AUTO) private Lon

我有一个实体类

public class CategoryEntity implements Serializable {
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    private Long id;

    @Column(length = 30, nullable = false)
    private String categoryKeyId;

    @Column(nullable = false)
    private String name;

    //Here mappedBy indicates that the owner is in the other side
    @OneToMany(fetch = FetchType.EAGER, mappedBy = "category", cascade = CascadeType.ALL)
    private List<ProductEntity> products;

    @ManyToOne(optional = true, fetch = FetchType.LAZY)
    private CategoryEntity parent;

    // allow to delete also subcategories
    @OneToMany(mappedBy="parent", cascade = CascadeType.ALL)
    private List<CategoryEntity> subCategories;
}
到目前为止,一切都很好,这正是我所期待的。我的问题是如何创建一个新类别

我的DTO层是:

CREATE TABLE `categories` (
  `id` bigint(20) NOT NULL,
  `category_key_id` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `parent_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKsaok720gsu4u2wrgbk10b5n8d` (`parent_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
@Getter @Setter
public class CategoryDto implements Serializable {
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private static final long serialVersionUID = 1L;

    private long id;
    private int parentCategoryId;
    private String categoryKeyId;
    private String name;
    private List<CategoryDto> subCategories;
    private CategoryDto parentCategory;

}
@Getter @Setter
public class CategoryCreateRequestModel {
    private String name;
    private int parentCategory;
}
@Getter @Setter
public class CategoryCreateRest {
    private String categoryKeyId;
    private String name;
    private CategoryCreateRest parentCategory;
}
我检索一个json作为输出:

CREATE TABLE `categories` (
  `id` bigint(20) NOT NULL,
  `category_key_id` varchar(30) COLLATE utf8_unicode_ci NOT NULL,
  `name` varchar(255) COLLATE utf8_unicode_ci NOT NULL,
  `parent_id` bigint(20) DEFAULT NULL,
  PRIMARY KEY (`id`),
  KEY `FKsaok720gsu4u2wrgbk10b5n8d` (`parent_id`)
) ENGINE=MyISAM DEFAULT CHARSET=utf8 COLLATE=utf8_unicode_ci;
@Getter @Setter
public class CategoryDto implements Serializable {
    @Getter(AccessLevel.NONE)
    @Setter(AccessLevel.NONE)
    private static final long serialVersionUID = 1L;

    private long id;
    private int parentCategoryId;
    private String categoryKeyId;
    private String name;
    private List<CategoryDto> subCategories;
    private CategoryDto parentCategory;

}
@Getter @Setter
public class CategoryCreateRequestModel {
    private String name;
    private int parentCategory;
}
@Getter @Setter
public class CategoryCreateRest {
    private String categoryKeyId;
    private String name;
    private CategoryCreateRest parentCategory;
}
我的createCategory方法返回我期望的输出结果,并将CategoryCreateRequestModel作为输入

@PostMapping(
        consumes = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE },
        produces = { MediaType.APPLICATION_XML_VALUE, MediaType.APPLICATION_JSON_VALUE }
) 
public CategoryCreateRest createCategory(@RequestBody CategoryCreateRequestModel categoryCreateRest) throws Exception {
    CategoryCreateRest returnValue = new CategoryCreateRest();

    if( categoryCreateRest.getName().isEmpty())
        throw new NullPointerException(ErrorMessages.MISSING_REQUIRED_FIELDS.getErrorMessage());

    ModelMapper modelMapper = new ModelMapper();
    CategoryDto categoryDto = modelMapper.map(categoryCreateRest, CategoryDto.class);

    CategoryDto createdCategory = categoryService.createCategory(categoryDto);
    returnValue = modelMapper.map(createdCategory, CategoryCreateRest.class);

    return returnValue;
}
我的服务层:

@Override
public CategoryDto createCategory(CategoryDto categoryDto) {
    // check if category name and parentId are identicals
    if (categoryRepository.findByName(categoryDto.getName()) != null)
        throw new ApplicationServiceException("Record already in Database");

    ModelMapper modelMapper = new ModelMapper();
    CategoryEntity categoryEntity = modelMapper.map(categoryDto, CategoryEntity.class);

    // generate categoryKeyId
    String categoryKeyId = utils.generateCategoryKeyId(30);
    categoryEntity.setCategoryKeyId(categoryKeyId);

    CategoryEntity storedCategory = categoryRepository.save(categoryEntity);

    CategoryDto returnValue = modelMapper.map(storedCategory, CategoryDto.class);

    return returnValue;
}
例如,当我设置新类别时:

{
  "name": "catName",
  "parentCategoryId": 12
}

我得到一条500错误消息:无法执行语句;SQL[n/a];约束[主要];嵌套异常为org.hibernate.exception.ConstraintViolationException:无法执行语句“


显然,我的主键有问题,我看不出哪里出了问题。我不需要向这个json传递id,因为它应该自动生成。

尝试在db端添加一些
id
的生成技术(例如
自动增量
)你说得太对了!我必须用标识更改AUTO…不幸的是,我没有解决类别父项…添加hibernate版本以及您在描述中使用的dbms会很有用