May I know what I could have been doing wrong here. Whenever a
Role is deleted, those
Users under it should also be deleted (a typical parent-child relationship). However, I am getting these errors. Isn't it that @OnDelete(action=OnDeleteAction.CASCADE) should do that for me. Anyway, I am using Hibernate together with Spring Framework. For complete source code, kindly check my public SVN Repository
https://raseryu-projects.googlecode.com/svn/BaseApplicationFramework/trunkCode:
2010-06-28 14:42:25.033::WARN: Nested in org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'dataGenerator' defined in ServletContext resource [/WEB-INF/applicationContext.xml]: Invocation of init method failed; nested exception is org.springframework.dao.DataIntegrityViolationException: Could not execute JDBC batch update; SQL [delete from ROLE where ID=?]; constraint [null]; nested exception is org.hibernate.exception.ConstraintViolationException: Could not execute JDBC batch update:
java.sql.BatchUpdateException: Cannot delete or update a parent row: a foreign key constraint fails (`baseapplication`.`users`, CONSTRAINT `FK4D495E899AFC77B` FOREIGN KEY (`role_ID`) REFERENCES `role` (`ID`))
Role class
Code:
public class Role extends BaseModel {
@OneToMany(cascade = CascadeType.ALL, mappedBy = "role", fetch = FetchType.EAGER)
@org.hibernate.annotations.Cascade(value = org.hibernate.annotations.CascadeType.DELETE_ORPHAN)
@JoinColumn(name = "ROLE_ID", nullable = false)
@OnDelete(action=OnDeleteAction.CASCADE)
private Set<User> users;
/**
* Return set of users belonging to this role.
*
* @return set of users belonging to this role.
*/
public Set<User> getUsers() {
return this.users;
}
/**
* Set list of users belonging to this role.
*
* @param users
* list of users belonging to this role.
*/
public void setUsers(Set<User> users) {
this.users = users;
}
}
User class
Code:
public class User extends BaseModel {
@ManyToOne(optional = false)
private Role role;
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
}
DAO Class
Code:
@Repository(value = "baseDao")
@Transactional(propagation = Propagation.REQUIRED)
public abstract class BaseDaoImpl<T extends BaseModel> extends HibernateDaoSupport implements BaseDao<T> {
private Class<T> modelClass;
@SuppressWarnings("unchecked")
public BaseDaoImpl() {
super();
this.modelClass = (Class<T>) ((ParameterizedType) this.getClass().getGenericSuperclass()).getActualTypeArguments()[0];
}
@Override
public void delete(T t) {
this.getSession().delete(t);
}
}
ApplicationContext
Code:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:context="http://www.springframework.org/schema/context" xmlns:p="http://www.springframework.org/schema/p"
default-autowire="byName" xmlns:sec="http://www.springframework.org/schema/security"
xmlns:tx="http://www.springframework.org/schema/tx"
xsi:schemaLocation="http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.0.xsd
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd
http://www.springframework.org/schema/tx http://www.springframework.org/schema/tx/spring-tx-3.0.xsd
http://www.springframework.org/schema/context http://www.springframework.org/schema/context/spring-context-3.0.xsd">
<!-- Context -->
<context:component-scan base-package="ph.i.raseryu.*" />
<!-- Database Configuration -->
<bean id="propertyConfigurer" class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">
<property name="location">
<value>classpath:baseapplication.properties</value>
</property>
</bean>
<bean id="abstractSessionFactory" class="org.springframework.orm.hibernate3.annotation.AnnotationSessionFactoryBean">
<property name="dataSource" ref="dataSource" />
<property name="schemaUpdate" value="true" />
<property name="entityInterceptor" ref="auditLogInterceptor" />
<property name="eventListeners">
<map>
<entry key="post-update" value-ref="searchListener" />
<entry key="post-insert" value-ref="searchListener" />
<entry key="post-delete" value-ref="searchListener" />
</map>
</property>
<property name="hibernateProperties">
<props>
<prop key="hibernate.show_sql">false</prop>
<prop key="hibernate.cache.provider_class">org.hibernate.cache.EhCacheProvider </prop>
<prop key="hibernate.cache.use_second_level_cache">false</prop>
<prop key="hibernate.cache.use_query_cache">false</prop>
</props>
</property>
<property name="packagesToScan">
<list>
<value>ph.i.raseryu</value>
</list>
</property>
<property name="mappingLocations">
<list>
<value>classpath:hibernateTypes.hbm.xml</value>
</list>
</property>
</bean>
<bean id="searchListener" class="org.hibernate.search.event.FullTextIndexEventListener" />
<bean id="transactionManager" class="org.springframework.orm.hibernate3.HibernateTransactionManager"
p:sessionFactory-ref="sessionFactory" />
<tx:annotation-driven />
</beans>