-1

All I need help i create this simple class where Category have list of Categories. When i try to save the list of sub categories with the Parent category it's show below error.

Json:-

{
    "name": "n11111111",
    "detail": "detail",
    "status" : "AVAILABLE",
    "subCategories": [3, 12, 100, 7, 11] // id of sub-cat
}

Class:-

@Entity
@Table(name = "category")
public class Category{

    @Id
    @GeneratedValue(strategy= GenerationType.AUTO)
    @Column(nullable = false, updatable = false, name = "category_id")
    private Long id;

    @Column(name = "name", nullable=false)
    private String name;

    @Column(name = "detail", nullable=false)
    private String detail;

    @Column(nullable = false, name = "status")
    @Enumerated(EnumType.ORDINAL)
    private Status status;

    @OneToMany( targetEntity=Category.class, cascade=CascadeType.ALL)
    private List<Category> subCategories;

}

ERROR:- "message": "could not execute statement; SQL [n/a]; constraint [UK_76grwe00i7mrj7awuvhc3kx0n]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement",

MYSQL ERROR:- #1062 - Duplicate entry

Code:- Convert from Vo to POJO

private Categorie getCatToPojo(CategorieVo categorieVo, String type) {
    double startTime = System.nanoTime();
    logger.info("Start Vo To Pojo Categorie");
    // #:- case:-1 when no sub-cat there it save only below 3 attribute
    this.categorie = new Categorie();
    this.saveNameCat(categorieVo, type);
    this.categorie.setDetail(categorieVo.getDetail());
    this.categorie.setStatus(categorieVo.getStatus());
    // #:- case:-2 when have list of sub-cat then will exe then next process
    if((CollectionUtils.isNotEmpty(categorieVo.getSubCategories()) && categorieVo.getSubCategories().size() > 0) && type.equalsIgnoreCase("P")) {
        logger.debug("Sub-Process....SubCategories...init");
        // #:- S-Cat will be get and
        List<Categorie> subCategories = this.businessServer.findAllById(categorieVo.getSubCategories())
                .stream().filter(categorie1 -> categorie1.getName().startsWith("S-") == true ).collect(Collectors.toList());
        // #:- if any wrong id pass it will not give you the list
        if(CollectionUtils.isNotEmpty(subCategories) && subCategories.size() > 0) {
            this.categorie.setSubCategories(subCategories);
        }
        logger.debug("Sub-Process....SubCategories...End " + categorieVo.getSubCategories().toString());
    }
    logger.debug(SecurityUtil.getPerfLog("Process Time For Convert the Vo to POJO", this.categorie.toString(), startTime));
    logger.info("End Vo To Pojo Categorie");
    return categorie;
}

private void saveNameCat(CategorieVo categorieVo, String type) {

    switch (type) {
        case "P":
            // #:- P,S will join with name
            this.categorie.setName(type + "-" + categorieVo.getName());
            break;
        case "S":
            // #:- P,S will join with name
            this.categorie.setName(type + "-" + categorieVo.getName());
            break;
        default:
            logger.info("End Vo To Pojo Categorie With Exception");
            // #:- will throw error bad request of type
            throw new BadTypeException(" [ " + "Bad Request Type" + " ]--[ " + type + " ]");
    }
}
Nabeel Ahmed
  • 258
  • 1
  • 7
  • 23
  • 1
    Can I see the code that does the saving? In theory you're supposed to load the subCats first, create your parent catg, do all the setting parent dance then save parent... – Desorder Aug 21 '18 at 08:06
  • Possible duplicate of [How to create Hibernate Mapping for a self referencing table](https://stackoverflow.com/questions/29975751/how-to-create-hibernate-mapping-for-a-self-referencing-table) – Joakim Danielson Aug 21 '18 at 08:10
  • @Desorder sure plz view the code. i convert from vo to pojo and save the pojo class by use of simple repository interface method save – Nabeel Ahmed Aug 21 '18 at 08:22
  • AFAIK this would work out of the box with eclipse link as JPA implementation, where Hibernate does not accept that. I had to switch a project to hibernate and that is how I noticed. – maslan Aug 21 '18 at 12:25

2 Answers2

0

Once I have to do exact same thing. Here is the working code for same purpose :

@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;
    }
}
Emre Savcı
  • 3,034
  • 2
  • 16
  • 25
  • I have 2 Parent Categories like (A, B) and i also have 2 Sub-Categories like (1, 2) i want A have both sub-Cat and also B have both sub-cat and more cat... but in above it will create the `Column` but when i try to assign the sub cat to both it will not assign in that we only assign the sub cat only one parent while if we try to assign to any other Parent cat it will replace the old one – Nabeel Ahmed Aug 21 '18 at 13:21
  • I think it is better to create another table for relations and use @JoinTable annotation for it – Emre Savcı Aug 21 '18 at 14:57
0
insert into `db`.`category` values (1, 'a');

insert into `db`.`category` values (2, 'b');

insert into `db`.`category` values (3, 'c');

commit;

insert into `db`.`subcategory` values (1, 2);
insert into `db`.`subcategory` values (1, 3);

import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;

import org.hibernate.annotations.Cascade;
import org.hibernate.annotations.CascadeType;


@Entity
@Table(name = "category")
public class Category {


    @SuppressWarnings("unused")
    private static final long serialVersionUID = 1L;

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    @Column(name="id")
    private int id; 


    @Column(name="name")
    private String name;

    @ManyToMany(fetch=FetchType.EAGER)
    @Cascade({CascadeType.ALL})
    @JoinTable(name="subcategory", 
            joinColumns={@JoinColumn(name="idcategory")}, 
            inverseJoinColumns={@JoinColumn(name="idsubcategory")}) 
    private Set<Category> catlist;


    public int getId() {
        return id;
    }


    public void setId(int id) {
        this.id = id;
    }


    public String getName() {
        return name;
    }


    public void setName(String name) {
        this.name = name;
    }


    public Set<Category> getCatlist() {
        return catlist;
    }


    public void setCatlist(Set<Category> catlist) {
        this.catlist = catlist;
    } 


}
Bacem W.
  • 92
  • 4
  • as showed in the bottom of the response you should create two tables * Category having (id , name) * Subcategory (idcategory, idsubcategory) idcategory references category.id idsubcategory references category.id in the exemple (inserted values) category 1 (id = 1) has two subcategories (id=2 and id=3) – Bacem W. Aug 21 '18 at 12:26