2010-10-31 48 views
1
public class Group{ 
@ManyToMany(fetch=FetchType.EAGER, cascade=CascadeType.ALL, mappedBy="groups") 
public Set<User> getUsers() { 
    if(users == null) 
    return new HashSet<User>(); 
    else 
    return users; 
} 
public void setUsers(Set<User> users) { 
    this.users = users; 
} 
} 

public class User{ 

public void setGroups(Set<Group> groups) { 
    this.groups = groups; 
} 
    @ManyToMany(cascade = CascadeType.ALL) 
public Set<Group> getGroups() { 
    return groups; 
} 
} 

現在,如果我刪除一個用戶,他應該自動從他在,這就是我期待反正所有組中刪除。從多對多集合刪除成員拋出org.h2.jdbc.JdbcBatchUpdateException

我得到的卻是這個醜陋的例外:

> Exception in thread "main" 
> org.springframework.dao.DataIntegrityViolationException: 
> Could not execute JDBC batch update; 
> SQL [delete from USERS where ID=?]; 
> constraint ["FKB4DD17BD8FCA5D9E: 
> PUBLIC.GROUPS_USERS FOREIGN 
> KEY(USERS_ID) REFERENCES 
> PUBLIC.USERS(ID)"; SQL statement: 
> delete from USERS where ID=? 
> [23003-143]]; nested exception is 
> org.hibernate.exception.ConstraintViolationException: 
> Could not execute JDBC batch update 
> at 
> org.springframework.orm.hibernate3.SessionFactoryUtils.convertHibernateAccessException(SessionFactoryUtils.java:637) 
> at 
> org.springframework.orm.jpa.vendor.HibernateJpaDialect.translateExceptionIfPossible(HibernateJpaDialect.java:97) 
> at 
> org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:471) 
> 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:393) 
> 2010-10-31 19:41:19.044 
> java[28733:903] An uncaught exception 
> was raised 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 $Proxy22.removeUser(Unknown 
> Source) at 
> com.stone.gym.controller.UserController.removeUser(UserController.java:43) 
> at 
> com.stone.gym.view.UserView$3.handleEvent(UserView.java:121) 
> at 
> org.eclipse.swt.widgets.EventTable.sendEvent(Unknown 
> Source) at 
> org.eclipse.swt.widgets.Display.sendEvent(Unknown 
> Source) at 
> org.eclipse.swt.widgets.Widget.sendEvent(Unknown 
> Source) at 
> org.eclipse.swt.widgets.Widget.sendEvent(Unknown 
> Source) at 
> org.eclipse.swt.widgets.Widget.sendEvent(Unknown 
> Source) at 
> org.eclipse.swt.widgets.Widget.notifyListeners(Unknown 
> Source) at 
> org.eclipse.swt.widgets.Display.runDeferredEvents(Unknown 
> Source) at 
> org.eclipse.swt.widgets.Display.readAndDispatch(Unknown 
> Source) at 
> com.stone.gym.controller.FrontController.run(FrontController.java:30) 
> at 
> com.stone.gym.StoneGym.main(StoneGym.java:21) 
> 2010-10-31 19:41:19.045 
> java[28733:903] Java exception 
> occurred Caused by: 
> org.hibernate.exception.ConstraintViolationException: 
> Could not execute JDBC batch update 
> at 
> org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71) 
> at 
> org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43) 
> at 
> org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:254) 
> at 
> org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:266) 
> at 
> org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:172) 
> at 
> org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:298) 
> at 
> org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27) 
> at 
> org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1001) 
> at 
> org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:339) 
> at 
> org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106) 
> at 
> org.hibernate.ejb.TransactionImpl.commit(TransactionImpl.java:54) 
> at 
> org.springframework.orm.jpa.JpaTransactionManager.doCommit(JpaTransactionManager.java:467) 
> ... 19 more Caused by: 
> org.h2.jdbc.JdbcBatchUpdateException: 
> Referential integrity constraint 
> violation: "FKB4DD17BD8FCA5D9E: 
> PUBLIC.GROUPS_USERS FOREIGN 
> KEY(USERS_ID) REFERENCES 
> PUBLIC.USERS(ID)"; SQL statement: 
> delete from USERS where ID=? 
> [23003-143] at 
> org.h2.jdbc.JdbcPreparedStatement.executeBatch(JdbcPreparedStatement.java:1101) 
> at 
> org.apache.commons.dbcp.DelegatingPreparedStatement.executeBatch(DelegatingPreparedStatement.java:231) 
> at 
> org.hibernate.jdbc.BatchingBatcher.doExecuteBatch(BatchingBatcher.java:48) 
> at 
> org.hibernate.jdbc.AbstractBatcher.executeBatch(AbstractBatcher.java:247) 
> ... 28 more 

回答

3

現在,如果我刪除一個用戶,他應該自動從他在這就是我期待反正所有組中刪除。

我懷疑你沒有刪除一個給定的User,因此在連接表級別約束違反異常之前正確更新UserGroup之間的「鏈路兩端」。類似的東西:

for (Group group : user.getGroups()) { 
    group.getUsers().remove(user); 
} 
em.remove(user); 

而且,我不知道爲什麼你級聯的所有操作(你想刪除組刪除用戶的時候?)

+0

+1:我正在處理這樣的事情,但不必要地得到了更多的冗長。 – 2010-11-01 13:22:38

0

您需要集團的倒數設置爲true和刪除用戶將刪除相對關係。但是,如果您的用戶級聯是全部,則組也將被刪除。所以把它改爲保存更新。

帕斯卡的建議是一種更好的方法。明確刪除關係總是首選。

0

您可以使用此技術,在休眠站點(http://docs.jboss.org/hibernate/annotations/3.5/reference/en/html_single/#entity-mapping-association)中進行了描述。請務必刪除mappedBy from @ManyToMany in Group entity。

public class Group{ 
@ManyToMany(fetch=FetchType.EAGER) 
@JoinTable(name = "groups_users", 
     joinColumns = @JoinColumn(name = "groups_id"), 
     inverseJoinColumns = @JoinColumn(name = "users_id")) 
public Set<User> getUsers() { 
    if(users == null) 
    return new HashSet<User>(); 
    else 
    return users; 
} 
public void setUsers(Set<User> users) { 
    this.users = users; 
} 
} 

public class User{ 

public void setGroups(Set<Group> groups) { 
    this.groups = groups; 
} 
@ManyToMany 
@JoinTable(name = "groups_users", 
     joinColumns = @JoinColumn(name = "users_id"), 
     inverseJoinColumns = @JoinColumn(name = "groups_id")) 
public Set<Group> getGroups() { 
    return groups; 
} 
}