davidvera
davidvera

Reputation: 1489

Hibernate save an object with data concerning "parent"

I'm sending a JSON object in order to persist it in a database. I consider that the category already exists and cannot be modified (values are set with a dropdown list for example).

{
    "productKeyId": "W7cpgwmb8LOkE7u5vRZLVoY8mXWmnR",
    "name": "Pizzaé miam miam",
    "price": 344.0,
    "qty": 15,
    "imgPath": "new/pathImage",
    "category": {
        "categoryKeyId": "VMz7EM6tNfoOAQtO1SHPYcH14jj0Cy",
        "name": "Fish"
    }
}

To build this json i created two model classes :

@Getter @Setter
public class ProductCreateRequestModel {
    private String productKeyId;
    private String name;
    private double price;
    private int qty;
    private String imgPath;

    private CategoryRequestCreateProductModel category;
}

And :

@Getter @Setter
public class CategoryRequestCreateProductModel {
    private String name;
    private String categoryKeyId;
}

In my controller :

public ProductRest createProduct(@RequestBody ProductCreateRequestModel productRequestModel) throws Exception {
    ProductRest returnValue = new ProductRest();

    CategoryRequestCreateProductModel categoryRequestCreateProductModel = new CategoryRequestCreateProductModel();
    //CategoryRest categoryRest = new CategoryRest();

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

    if(productRequestModel.getName().isEmpty() || productRequestModel.getPrice() <= 0 || productRequestModel.getCategory() == null)
        throw new ApplicationServiceException(ErrorMessages.MISSING_REQUIRED_FIELDS.getErrorMessage());

    ProductDto productDto = new ProductDto();
    productDto.setCategory(categoryDto);
    productDto = modelMapper.map(productRequestModel, ProductDto.class);

    ProductDto createdProduct = productService.createProduct(productDto);
    returnValue = modelMapper.map(createdProduct, ProductRest.class);

    return returnValue;
}

Finally at my service layer :

@Override
public ProductDto createProduct(ProductDto productDto) {
    if ( productRepository.findByName(productDto.getName()) != null)
        throw new ApplicationServiceException("Record already in Database");

    CategoryDto categoryDto = productDto.getCategory();
    productDto.setCategory(categoryDto);

    ModelMapper modelMapper = new ModelMapper();
    ProductEntity productEntity = modelMapper.map(productDto, ProductEntity.class);
    String productKeyId = utils.generateProductKeyId(30);
    productEntity.setProductKeyId(productKeyId);

    ProductEntity storedProduct = productRepository.save(productEntity);

    return modelMapper.map(storedProduct, ProductDto.class);
}

My ProductDto layer :

private Long id;
private String name;
private String productKeyId;
private double price;
private int availableQty;
private String imgPath;

private CategoryDto category = new CategoryDto();

My CategoryDto:

private long id;
private String categoryKeyId;
private String name;

private CategoryDto parentCategory;
private List<CategoryDto> subCategories;

private String parentCategoryKeyId;

private Long parentCategoryId;

Finally my productEntity

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

@Column(nullable = false)
private String productKeyId;

// many to one relationship with category
@ManyToOne
@JoinColumn(name = "category_id")
private CategoryEntity category;

@Column(nullable = false)
private String name;

@Column(nullable = false)
private double price;

@Column(nullable = false)
private int availableQty;

private String imgPath;

And my CategoryEntity

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

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

@Column(nullable = false)
private String name;

@ManyToOne(optional = true, fetch = FetchType.LAZY)
@JoinColumn(name="parent_id", nullable=true)
private CategoryEntity parentCategory;

// allow to delete also subcategories
@OneToMany(mappedBy="parentCategory", cascade = CascadeType.ALL)
private List<CategoryEntity> subCategories;


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

When i run the app and send the request I obtain :

1) Converter org.modelmapper.internal.converter.NumberConverter@57364b9e failed to convert java.lang.String to long.

1 error] with root cause

java.lang.NumberFormatException: For input string: "VMz7EM6tNfoOAQtO1SHPYcH14jj0Cy"
    at java.base/java.lang.NumberFormatException.forInputString(NumberFormatException.java:65) ~[na:na]
    at java.base/java.lang.Long.parseLong(Long.java:692) ~[na:na]
    at java.base/java.lang.Long.valueOf(Long.java:1144) ~[na:na]

Upvotes: 0

Views: 49

Answers (1)

Jonathan JOhx
Jonathan JOhx

Reputation: 5968

The issue is when deserializing, try this to fix it.

public ProductRest createProduct(@RequestBody ProductCreateRequestModel productRequestModel) throws Exception {
    ProductRest returnValue = new ProductRest();

    CategoryRequestCreateProductModel categoryRequestCreateProductMode = modelMapper.map(productRequestModel.getCategory(), CategoryRequestCreateProductModel.class);

    CategoryDTO categoryDTO = new CategoryDTO();
    categoryDTO.setCategoryKeyId(categoryRequestCreateProductMode.getCategoryKeyId());
    categoryDTO.setName(categoryRequestCreateProductMode.getName());

    ----  
}

Upvotes: 1

Related Questions