Many to One Relationship While removing child object it's throwing exception
Asked Answered
S

3

2

I am doing Many To One relationship using JPA . While deleting child object from Child table it's throwing exception.

Below is My code:

Project.java

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  @Column(name="id")
  private int id;
  @Column(name="projectName")
  private String projectName;
  @Column(name="projectDesc")
  private String projectDesc; 

  @ManyToOne(cascade=CascadeType.ALL, fetch=FetchType.EAGER)
  @JoinColumn(name="companyId")

Company.java

  @Id
  @GeneratedValue(strategy=GenerationType.IDENTITY)
  @Column(name="id")
  private int id;
  @Column(name="compName")
  private String compName;
  @Column(name="address")
  private String address;

Below is Insert code:

InserAction.java

public static void main(String[] args) {
    Company comp2 = new Company();
    comp2.setCompName("IBM");
    comp2.setAddress("Bangalore");

    Project pro2 = new Project();
    pro2.setProjectName("Management System");
    pro2.setProjectDesc("System");
    pro2.setCompany(comp2);
    EntityManager entityManager = EntityManagerUtil.getEmf().createEntityManager(); 
    try{
      EntityTransaction entr = entityManager.getTransaction();
      entr.begin();
      entityManager.persist(pro2);
      entr.commit();
    }
 }

DeleteAction.java

EntityManager entityManager = EntityManagerUtil.getEmf()
            .createEntityManager();
    try {
        EntityTransaction entr = entityManager.getTransaction();
        entr.begin();       
        Project project = entityManager.find(Project.class,5);
        entityManager.remove(project);      

        entr.commit();
      }

Exception is

Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`prabha`.`project`, CONSTRAINT `FK_project_companyId` FOREIGN KEY (`companyId`) REFERENCES `company` (`id`))
Error Code: 1451
  Call: DELETE FROM company WHERE (id = ?)
  bind => [1 parameter bound]
  Query: DeleteObjectQuery(com.demo.manytoone.Company@301db5ec)

While deleting project object from Project table it' throwing above exception how can I over come this.

Starbuck answered 4/2, 2014 at 6:44 Comment(12)
In Project.java try removing "cascade=CascadeType.ALL", when removing a Project the remove operation will propagate to Company, if Company has more than one Project the remove will fail.Mousse
If I removed that one working fine but while inserting it's throwing exceptionStarbuck
Can you post the code that does the insert ?Mousse
@Mousse I added insert code check it onceStarbuck
Try to persist first comp2 than add it to pro2, if you want to cascade the persist form pro2 to comp2, add CascadeType.PERSIST in Project or follow @Aditya solution.Mousse
@Mousse while doing like that insert and delete working is fine. And If I remove all child objects the parent class object is not deleting. According to Many to one relationship If child object remove parent object should remove right here that's not happening. Thank you very muchStarbuck
@codegeek According to many to one relationship, if child object is removed then parent object is not removed, only the relation between child and parent object is removed, because the parent can have multiple child, so the other children would become orphans if we remove parent object. Have a look over these links: 1). en.wikibooks.org/wiki/Java_Persistence/Relationships#Cascading 2). en.wikibooks.org/wiki/Java_Persistence/….Preamplifier
@Preamplifier yes you are right, But while saving single object in both parent and child it's saving and while deleting child object it's removing parent object also. why it's happen? Thank youStarbuck
What is your CascadeType? Is it CascadeType.REMOVE after editing?Preamplifier
@Preamplifier CascadeType.ALLStarbuck
I have added some more info in my answer at end. You can specify all the CascadeType as applicable to your requirements.Preamplifier
let us continue this discussion in chatPreamplifier
P
0

You should not use CascadeType.ALL, try using CascadeType.MERGE

The meaning of CascadeType.ALL is that the persistence will propagate (cascade) all EntityManager operations (PERSIST, REMOVE, REFRESH, MERGE, DETACH) to the relating entities.

It seems in your case to be a bad idea, as removing an Project would lead to removing the related Company when you are using CAscadeType.ALL. As a Company can have multiple projects, the other projects would become orphans. However the inverse case (removing the Company) would make sense - it is safe to propagate the removal of all projects belonging to a Company if this company is deleted.

You can also use various CascadeTypes, for e.g. cascade = {CascadeType.PERSIST,CascadeType.MERGE}. So use all those that applied to you.

For more info.

Preamplifier answered 4/2, 2014 at 7:3 Comment(1)
I added that one single project record is deleted but while inserting it's throwing "Relationship that was not marked cascade PERSIST" exception. thank youStarbuck
S
0
 @ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.EAGER)

The above code will resolve your issue. If you observe source code of annotation ManyToOne it has an array of cascade type so you can map multiple cascade types

Setting answered 4/2, 2014 at 9:14 Comment(0)
D
0

You got MySQLIntegrityConstraintViolationException. It means there are tables in the database you're binding. You should map when you set up the many to one relationship tables. Company should be able to get more than one project. So you have to define the list of projects.

Project.java

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="projectName")
private String projectName;
@Column(name="projectDesc")
private String projectDesc; 

@ManyToOne
@JoinColumn(name="companyId")
private Company company;

Company.java

@Id
@GeneratedValue(strategy=GenerationType.IDENTITY)
@Column(name="id")
private int id;
@Column(name="compName")
private String compName;
@Column(name="address")
private String address;

@OneToMany(mappedBy="company", fetch=FetchType.EAGER)
private List<Project> projects;
Dextrogyrate answered 4/2, 2014 at 9:28 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.