I have 2 entities being in typical parent-child relation: RoutingType that can have multiple RoutingParameters. JPA mapping looks like this:
@Entity
@Table(name = "ROUTING_TYPE")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class RoutingType {
@Id
private Long id;
@OneToMany(mappedBy = "routingType", cascade = CascadeType.ALL, orphanRemoval = true)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<RoutingProperty> properties = new HashSet<>();
// Getters & Setters
}
@Entity
@Table(name = "ROUTING_PROPERTY")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class RoutingProperty {
@Id
@Column(name = "ID")
private Long id;
@ManyToOne
@JoinColumn(name = "ROUTING_TYPE_ID", nullable = false)
private RoutingType routingType;
// Getters & Setters
}
To manage the data I use spring JpaRepository:
@Repository
public interface RoutingTypeRepository extends JpaRepository<RoutingType, Long> {
}
My problem is that when I try to delete the parent (RoutingType) having at least one RoutingProperty, then I get the ConstraintViolationException.
This is how I delete the object:
routingTypeRepo.deleteById(id);
And these are detailed logs with sql statements:
org.hibernate.SQL : select routingtyp0_.id as id1_93_0_, routingtyp0_.name as name2_93_0_, routingtyp0_.property_priority as property_priority3_93_0_, routingtyp0_.version as version4_93_0_ from routing_type routingtyp0_ where routingtyp0_.id=?
o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [646]
org.hibernate.SQL : select properties0_.routing_type_id as routing_type_id4_88_0_, properties0_.id as id1_88_0_, properties0_.id as id1_88_1_, properties0_.name as name2_88_1_, properties0_.routing_type_id as routing_type_id4_88_1_, properties0_.param as param3_88_1_, properties0_.web_service_endpoint_id as web_service_endpoi5_88_1_, webservice1_.id as id1_104_2_, webservice1_.authorization_type as authorization_type2_104_2_, webservice1_.name as name3_104_2_, webservice1_.password as password4_104_2_, webservice1_.url as url5_104_2_, webservice1_.username as username6_104_2_ from routing_properties properties0_ left outer join web_service_endpoint webservice1_ on properties0_.web_service_endpoint_id=webservice1_.id where properties0_.routing_type_id=?
o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [646]
org.hibernate.SQL : delete from routing_properties where id=?
o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [884]
org.hibernate.SQL : delete from routing_type where id=? and version=?
o.h.type.descriptor.sql.BasicBinder : binding parameter [1] as [BIGINT] - [646]
o.h.type.descriptor.sql.BasicBinder : binding parameter [2] as [INTEGER] - [0]
o.h.engine.jdbc.spi.SqlExceptionHelper : SQL Error: 2292, SQLState: 23000
o.h.engine.jdbc.spi.SqlExceptionHelper : ORA-02292: integrity constraint (FK_ROUTINGPROPERTY_ROUTINGTYPE) violated - Child record found
o.h.i.ExceptionMapperStandardImpl : HHH000346: Error during managed flush [org.hibernate.exception.ConstraintViolationException: could not execute statement]
o.z.p.spring.web.advice.AdviceTrait : Internal Server Error
org.springframework.dao.DataIntegrityViolationException: could not execute statement; SQL [n/a]; constraint [FK_ROUTINGPROPERTY_ROUTINGTYPE]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement
The weard thing about this case is that in the logs we can clearly see that hibernate deletes RoutingProperty before RoutingType deletion, but Oracle still complains that there's record found. I should add that all statements are executed at the transaction commit, not at the moment of RoutingTypeRepository.deleteById() method call.
What am I missing? Is there some possibility that Hibernate executes SQL queries in different order than logged?
I use Java 8, Spring Boot 2.0.3, Hibernate 5.2.17.Final, Oracle 11.2.0.3.0.