Hibernate:could not delete collection

这是引用http://qindingsky.blog.163.com/blog/static/312233620083103151423/的文章

Hibernate:could not delete collection

Spring 2008-04-10 15:15:01 阅读411 评论1   字号: 订阅

此异常一般出现在删除one-to-many设置的级联对象集合时,其原因往往是因为没有正确设置好一对多映射关系中的inverse属性(inverse决定了主控方和被控方)。

首先是实例程序

public static void delete()throws Exception{
Session session=sessionfactory.openSession();
Transaction tx=null;
try{
   tx=session.beginTransaction();
   Customers customer=(Customers)session.get(Customers.class,new Long(1)); 
   session.delete(customer); 
   tx.commit();
}catch(Exception e){
if(tx != null){
tx.rollback();
}throw e;
}finally{
session.close();
}
}
当在customer的orm文件中没有设置inverse属性或设置为inverse=false(默认值)时,此时customer为主控方,由customer负责维护关联关系,删除customer会出现此异常。
以下是报的错误:
Hibernate: select customers0_.ID as ID1_0_, customers0_.NAME as NAME1_0_ from do.dbo.CUSTOMERS customers0_ where customers0_.ID=?
Hibernate: select orders0_.CUSTOMER_ID as CUSTOMER3_1_, orders0_.ID as ID1_, orders0_.ID as ID2_0_, orders0_.ORDER_NUMBER as ORDER2_2_0_, orders0_.CUSTOMER_ID as CUSTOMER3_2_0_ from do.dbo.ORDERS orders0_ where orders0_.CUSTOMER_ID=?
Hibernate: update do.dbo.ORDERS set CUSTOMER_ID=null where CUSTOMER_ID=?
Exception in thread "main" org.hibernate.exception.ConstraintViolationException: could not delete collection: [com.hib.Customers.orders#1]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:71)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:980)
at org.hibernate.action.CollectionRemoveAction.execute(CollectionRemoveAction.java:28)
at org.hibernate.engine.ActionQueue.execute(ActionQueue.java:248)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:232)
at org.hibernate.engine.ActionQueue.executeActions(ActionQueue.java:141)
at org.hibernate.event.def.AbstractFlushingEventListener.performExecutions(AbstractFlushingEventListener.java:297)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:27)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:985)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:333)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at com.test.Business.delete(Business.java:67)
at com.test.Business.main(Business.java:78)
Caused by: java.sql.SQLException: 无法将 NULL 值插入列 'CUSTOMER_ID',表 'do.dbo.ORDERS';该列不允许空值。UPDATE 失败。
at net.sourceforge.jtds.jdbc.SQLDiagnostic.addDiagnostic(SQLDiagnostic.java:365)
at net.sourceforge.jtds.jdbc.TdsCore.tdsErrorToken(TdsCore.java:2781)
at net.sourceforge.jtds.jdbc.TdsCore.nextToken(TdsCore.java:2224)
at net.sourceforge.jtds.jdbc.TdsCore.getMoreResults(TdsCore.java:628)
at net.sourceforge.jtds.jdbc.JtdsStatement.processResults(JtdsStatement.java:525)
at net.sourceforge.jtds.jdbc.JtdsStatement.executeSQL(JtdsStatement.java:487)
at net.sourceforge.jtds.jdbc.JtdsPreparedStatement.executeUpdate(JtdsPreparedStatement.java:421)
at org.hibernate.jdbc.NonBatchingBatcher.addToBatch(NonBatchingBatcher.java:23)
at org.hibernate.persister.collection.AbstractCollectionPersister.remove(AbstractCollectionPersister.java:970)
... 11 more

错误的原因在于你删除了这个customer对象的时候,不是将对应order表中的和这个customer相关的记录直接删除,而是将这些记录的customer_id这个字段设置为NULL,但是你的这个字段又是not-null,因此会出现"Caused by: java.sql.SQLException: 无法将 NULL 值插入列 'CUSTOMER_ID',表 'do.dbo.ORDERS';该列不允许空值。UPDATE 失败。 "的提示

Hibernate: select customers0_.ID as ID1_0_, customers0_.NAME as NAME1_0_ from do.dbo.CUSTOMERS customers0_ where customers0_.ID =?     //取这个对象

Hibernate: select orders0_.CUSTOMER_ID as CUSTOMER3_1_, orders0_.ID as ID1_,  orders0_.ID as ID2_0_, orders0_.ORDER_NUMBER as ORDER2_2_0_, orders0_.CUSTOMER_ID as CUSTOMER3_2_0_ from do.dbo.ORDERS orders0_ where orders0_.CUSTOMER_ID =?    //取出级联对象

Hibernate: update do.dbo.ORDERS set CUSTOMER_ID=null where CUSTOMER_ID=?    

//级联更新,把null赋给非null ,会出问题的

解决办法:

在customer的映射文件中,设置集合的inverse=true,即customer作为受控方,此时order将作为主控方,由order管理关联关系。在one-to-many关系中,通常也是将many一方设为主控方。如

<set name="orders"  cascade="all" inverse="true">

<key column="CUSTOMER_ID"/>

<one-to-many class="**.**.Order" />

</set>

补充的是除了删除Customer对象会出现这种情况,并且通过Custoemr.Orders.remove(order), update(Customer),来删除对应的Order也会出现类似的错误

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值