-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: Cascade delete problem
PostPosted: Wed Jul 03, 2013 7:15 am 
Newbie

Joined: Wed Oct 24, 2012 3:47 am
Posts: 10
Location: Germany
Hello forum,

this time I have a complex problem getting may object graph deleted properly. I have left out some parts of object relations since they are very complex and large in reality and would complicate understanding of this post.
What I have I a central parent class called 'Controller'. Controller has a two OneToMany relations with join tables:

Code:
@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "ControllerInterface", joinColumns = @JoinColumn(name = "controllerId"), inverseJoinColumns = @JoinColumn(name = "interfaceId"))
@Fetch(FetchMode.SUBSELECT)
@OrderColumn(name = "interfaceIndex")
private final List<HardwareInterface> hardwareInterfaces = new ArrayList<>();

@OneToMany(fetch = FetchType.LAZY, cascade = CascadeType.ALL)
@JoinTable(name = "ControllerHardwareModule", joinColumns = @JoinColumn(name = "controllerId"), inverseJoinColumns = @JoinColumn(name = "hardwareModuleId"))
@Fetch(FetchMode.SUBSELECT)
@OrderColumn(name = "moduleIndex")
private final List<HardwareModule> hardwareModules = new ArrayList<>();


Both of the mapped classes are actually base classes to concrete classes. So there is a 'SerialInterface' class derived from HardwareInterface and an 'Extension' class derived from HardwareModule that uses one of the controller's hardware interfaces. Lets take a look at Extension which has a ManyToOne relation to hardware interface:

Code:
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = PROPERTY_HARDWARE_INTERFACE, nullable = false)
private HardwareInterface hardwareInterface;


Now the problem seems to be that when I delete the controller, hibernate issues the cascading deletes in the wrong order. It trys to first delete the hardware interfaces which fails with a constraint violation exception in the Extension table.
Delete statement sequence from log file:
Quote:
delete from ControllerInterface where controllerId=?
... left out some unnecessary deletes ...
delete from SerialInterface where id=?
delete from HardwareInterface where id=? and version=?


The stack trace is as follows:

Quote:
org.springframework.dao.DataIntegrityViolationException: The DELETE statement conflicted with the REFERENCE constraint "FK31BF5B4B2C9DE801". The conflict occurred in database "test", table "dbo.Extension", column 'hardwareInterface'.; SQL [n/a]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: The DELETE statement conflicted with the REFERENCE constraint "FK31BF5B4B2C9DE801". The conflict occurred in database "test", table "dbo.Extension", column 'hardwareInterface'.
at org.springframework.orm.hibernate4.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:159)
at org.springframework.orm.hibernate4.HibernateTransactionManager.convertHibernateAccessException(HibernateTransactionManager.java:606)
at org.springframework.orm.hibernate4.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:488)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:754)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:723)
at org.springframework.transaction.interceptor.TransactionAspectSupport.commitTransactionAfterReturning(TransactionAspectSupport.java:394)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:120)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:202)
at $Proxy140.delete(Unknown Source)


From what I have seen so far I guess that it is a problem, that the relation in the HardwareModule is unidirectional. So Hibernate does not know that it should delete the HardwareInterfaces first. But I cannot make the relation bidirectional because there are other classes using HardwareInterfaces that have no common base class that I could use to materialize the not-owning side.
Has anyone had a similiar scenario and found a solution to this? Sure I could introduce such a base class but that would cause even more joins when reading the database then I already have.

_________________
Regards,

Sebastian


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.