多对一关系在删除子对象时,它会抛出异常

时间:2014-02-04 06:44:48

标签: java jpa many-to-one

我正在使用JPA进行多对一关系。从Child表中删除子对象时,它会抛出异常。

以下是我的代码:

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;

下面是插入代码:

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();
      }

例外是

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)

从Project表中删除项目对象时,它会抛出异常,我该如何解决这个问题。

3 个答案:

答案 0 :(得分:0)

  

您不应使用CascadeType.ALL,请尝试使用CascadeType.MERGE

CascadeType.ALL 的含义是持久性会将所有EntityManager操作(PERSIST,REMOVE,REFRESH,MERGE,DETACH)传播(级联)到相关实体。

在您的情况下似乎是个坏主意,因为在使用CAscadeType.ALL时删除Project会导致删除相关的Company。由于Company可以有多个projects,其他projects会成为孤儿。但是相反的情况(删除Company)会有意义 - 如果删除此公司,则传播删除属于projects的所有Company是安全的。

您还可以使用各种CascadeTypes,例如 cascade = {CascadeType.PERSIST,CascadeType.MERGE}。 所以请使用适合您的所有内容。

了解更多info

答案 1 :(得分:0)

 @ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.EAGER)

上述代码将解决您的问题。如果你观察注释的源代码ManyToOne它有一个级联类型的数组,所以你可以映射多个级联类型

答案 2 :(得分:0)

你有MySQLIntegrityConstraintViolationException。这意味着您绑定的数据库中有表。您应该在设置多对一关系表时进行映射。公司应该能够获得多个项目。所以你必须定义项目列表。

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;