【问题标题】:Many to One Relationship While removing child object it's throwing exception多对一关系删除子对象时抛出异常
【发布时间】:2014-02-04 06:44:47
【问题描述】:

我正在使用 JPA 建立多对一关系。从子表中删除子对象时会引发异常。

下面是我的代码:

项目.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")

公司.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.java 中尝试删除“cascade=CascadeType.ALL”,当删除一个项目时,删除操作将传播到公司,如果公司有多个项目,删除将失败。
  • 如果我删除了那个工作正常但插入时抛出异常
  • 你能贴出插入的代码吗?
  • @Faton 我添加了插入代码检查一次
  • 尝试先持久化comp2而不是添加到pro2,如果要将持久化形式pro2级联到comp2,请在Project中添加CascadeType.PERSIST或关注@Aditya解决方案。

标签: java jpa many-to-one


【解决方案1】:
 @ManyToOne(cascade={CascadeType.MERGE, CascadeType.PERSIST}, fetch=FetchType.EAGER)

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

【讨论】:

    【解决方案2】:

    你不应该使用 CascadeType.ALL,尝试使用 CascadeType.MERGE

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

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

    您还可以使用各种 CascadeType,例如 级联 = {CascadeType.PERSIST,CascadeType.MERGE}。 因此,请使用所有适用于您的方法。

    了解更多info

    【讨论】:

    • 我补充说,一个项目记录被删除,但在插入时抛出“未标记级联 PERSIST 的关系”异常。谢谢
    【解决方案3】:

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

    项目.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;
    

    公司.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;
    

    【讨论】:

      猜你喜欢
      • 2020-04-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-09-19
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多