4

I have a table relation defined as show below and I am trying to cascade persistance and delete from Entity2(Table2) mean delete recor from table2 should remove the entry in table3 and saving data in table2 persist the related data in table3 as well.

                     oneToMany                       oneToMany 

Table1(Entity1) (parent) --------> Table2(Entity2) (Child to Table1) ---------> Table3(Child to Table2)(Entity3)

             oneToMany                          oneToMany

Table1 (parent) --------> Table4(Entity4) (Child to Table1) ---------> Table5(Child to Table4)(Entity5)

The Table1 is common parent to table2 and table4

Problem statement:

1) If I use CascadeType.REMOVE in Entity1 and {CascadeType.PERSIST,CascadeType.REMOVE} in its children (Entity2 and Entity4) then saving the record in table2 and deleting the record from table2 is getting cascaded to its child Entity3 (table3), but saving record to table1 is not getting cascade from to its children (Table2 and table4) as I am not using the cascade.persist in Entity1

2) If I use {CascadeType.PERSIST, CascadeType.REMOVE} in Entity1 and {CascadeType.PERSIST,CascadeType.REMOVE} in its children (Entity2 and Entity4) then saving the record in table2 is getting cascaded to its child Entity3 (table3) but on trying to delete the record from table2 is not getting deleted and also it is not getting cascaded to its child Entity3 (table3) and there is no exception either..... (From the log there is no delete query being executed, but in first case I can see the delete query being executed)

Could you help me out to find where I am going wrong.... Why adding CascadeType.PERSIST to Entity1 (Table1) will have impact on the deleting the record from table2?

Below Sample code :

Table1{

....

@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE,mappedBy=....})
public Set<Table2> getTable2() {
return table2;
}

}

Table2{

....

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(....)
public Table1 getTable1() {
return table1 
}


@OneToMany(cascade={CascadeType.PERSIST,CascadeType.REMOVE,mappedBy=....})
public Set<Table3> getTable3() {
    return table3;
}

}

Table3{

....

@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(....)
public Table2 getTable2() {
    return table2;

}

}

deepak al
  • 41
  • 3

2 Answers2

2

This article seems to describe your problem exactly. If what the author says is still true (the article's from 2010), the problem is that there is a mismatch between what actions JPA and Hibernate expect when persisting. If you're using an older Hibernate implementation, I'd first try upgrading to a newer version as I've never seen the problem in recent versions. If you can't upgrade (for example, you're constrained to using the version of Hibernate provided by your app server) or if upgrading doesn't work, replacing the JPA cascade annotations with the Hibernate cascade annotations may fix your problem. Using Hibernate annotations isn't a great solution because now your code isn't implementation-agnostic, but if it works it works.

What version of Hibernate/JPA/app server are you using?

Alvin Thompson
  • 5,388
  • 3
  • 26
  • 39
  • @deepakal: Hibernate 3.2?! Yeah, that version is ancient. Upgrade and it should work. If you can't upgrade, use the hibernate annotations (just for cascade type). – Alvin Thompson Jun 17 '14 at 15:59
1

It is likely that you are manually trying to remove an instance of Table2 without cleaning up references, so that your instance of Table1 is left referencing the removed instance of table2. The cascade persist option on the mapping will cause it to be reinserted - cancelling out your remove function.

You need to clean up reference to the objects you are trying to remove, as JPA will not do this for you and if not done, the cache is left out of synch with the database. When you try to remove an instance of Table2, you need to remove it from Table1's list as well.

Chris
  • 20,138
  • 2
  • 29
  • 43
  • It seems the issues is with the holding the references after removing the tables2..... after I added the line flush and reload the entity before persist the issue solved..... thanks Chris :) – deepak al Jun 17 '14 at 02:44
  • np, remember to mark the question as answered. JPA does not maintain relationships for you, so you must clean up references to removed objects and maintain both sides of bidirectional relationships to keep the object model in sync or issues like this will arise. – Chris Jun 17 '14 at 14:34