新足迹

 找回密码
 注册

精华好帖回顾

· vivid sydney不是只有歌劇院.....!! (2011-6-11) jmms_smmj · 夏日记忆,家乡的味道(62楼更新) (2011-1-2) 明河素月
· 大头怀念的北京小吃(五) --幼滑豌豆黄 (2007-12-19) datou2z · 周末-无车-孤独的探索者,19/07 Farmer‘s Market Brighton, Gardenworld (2025-5-21) jinluo
Advertisement
Advertisement
查看: 1401|回复: 7

[IT] 向IT编程高手求助 [复制链接]

发表于 2007-1-15 08:56 |显示全部楼层
此文章由 Frankman 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Frankman 所有!转贴必须注明作者、出处和本声明,并保持内容完整
I'm using NHibernate, which is a .NET port from Java Hibernate 2.1.7, and came across this issue. Hope someone help me out. Thanks a lot.

I have a bidirectional many-to-many mapping with index column. When I try to delete any child which is not the last one in the collection, deletion fails.


Mapping file at parent site:

  1.   <class name="EBSimple.Commerce.DomainModel.Category, EBSimple.Commerce.DomainModel" table="EBS_C_Category">
  2.       
  3.     <list name="Products"
  4.           table="EBS_C_Category_Product"
  5.           lazy="false"
  6.           cascade="save-update">
  7.       <key column="CategoryId"/>
  8.       <index column="DisplayOrder"/>
  9.       <many-to-many class="EBSimple.Commerce.DomainModel.Product, EBSimple.Commerce.DomainModel" column="ProductId"/>
  10.     </list>
  11.    
  12.   </class>
复制代码



Mapping file at child site:

  1.   <class name="EBSimple.Commerce.DomainModel.Product, EBSimple.Commerce.DomainModel" table="EBS_C_Product">

  2.     <bag name="Categories"
  3.          table="EBS_C_Category_Product"
  4.          inverse="true">
  5.       <key column="ProductId"/>
  6.       <many-to-many class="EBSimple.Commerce.DomainModel.Category, EBSimple.Commerce.DomainModel" column="CategoryId"/>
  7.     </bag>

  8.   </class>
复制代码



Table Schema:

  1. CREATE TABLE [dbo].[EBS_C_Category_Product] (
  2.    [CategoryId] [uniqueidentifier] NOT NULL ,
  3.    [ProductId] [uniqueidentifier] NOT NULL ,
  4.    [DisplayOrder] [int] NOT NULL
  5. )
复制代码




Code used to delete a child:


  1.          objCategory.Products.Remove(objProduct);
  2.          objProduct.Categories.Remove(objCategory);
  3.          SessionManager.GetSession().SaveOrUpdate(objCategory);
复制代码


Error message

  1. Violation of PRIMARY KEY constraint 'PK_EBS_C_Category_Product'. Cannot insert duplicate key in object 'EBS_C_Category_Product'.
  2. The statement has been terminated.

  3. Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code.

  4. Exception Details: System.Data.SqlClient.SqlException: Violation of PRIMARY KEY constraint 'PK_EBS_C_Category_Product'. Cannot insert duplicate key in object 'EBS_C_Category_Product'.
  5. The statement has been terminated.

  6. Source Error:


  7. Line 173:         CheckReaders();
  8. Line 174:         Prepare(cmd);
  9. Line 175:         return cmd.ExecuteNonQuery();
  10. Line 176:      }
  11. Line 177:
  12.   

  13. Source File: C:\temp\NHibernate-1.2.0.Beta2-debug\src\NHibernate\Impl\BatcherImpl.cs    Line: 175

  14. Stack Trace:


  15. [SqlException (0x80131904): Violation of PRIMARY KEY constraint 'PK_EBS_C_Category_Product'. Cannot insert duplicate key in object 'EBS_C_Category_Product'.
  16. The statement has been terminated.]
  17.    System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection) +857386
  18.    System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection) +734998
  19.    System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj) +188
  20.    System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj) +1838
  21.    System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString) +149
  22.    System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, Boolean async) +886
  23.    System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream, String method, DbAsyncResult result) +132
  24.    System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName, Boolean sendToPipe) +415
  25.    System.Data.SqlClient.SqlCommand.ExecuteNonQuery() +135
  26.    NHibernate.Impl.BatcherImpl.ExecuteNonQuery(IDbCommand cmd) in C:\temp\NHibernate-1.2.0.Beta2-debug\src\NHibernate\Impl\BatcherImpl.cs:175
  27.    NHibernate.Impl.NonBatchingBatcher.AddToBatch(IExpectation expectation) in C:\temp\NHibernate-1.2.0.Beta2-debug\src\NHibernate\Impl\NonBatchingBatcher.cs:36
  28.    NHibernate.Persister.Collection.BasicCollectionPersister.DoUpdateRows(Object id, IPersistentCollection collection, ISessionImplementor session) in C:\temp\NHibernate-1.2.0.Beta2-debug\src\NHibernate\Persister\Collection\BasicCollectionPersister.cs:222

  29. [ADOException: could not update collection rows: [EBSimple.Commerce.DomainModel.Category.Products#2877d2b2-e890-48dd-8908-98ac0183c17e]]
  30.    EBSimple.Core.NHibernateSessionManager.CommitTransaction() in C:\DNNDevEnvironment\DesktopModules\EBSimpleCommerce\Core\NHibernateSessionManager.cs:131
  31.    EBSimple.Commerce.HttpModules.NHibernateSessionModule.CommitAndCloseSession(Object sender, EventArgs e) in C:\DNNDevEnvironment\DesktopModules\EBSimpleCommerce\HttpModules\NHibernateSessionModule.cs:43
  32.    System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +92
  33.    System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +64

  34.   
  35. --------------------------------------------------------------------------------
  36. Version Information: Microsoft .NET Framework Version:2.0.50727.42; ASP.NET Version:2.0.50727.210
复制代码


Frank


--------------------------------------------------------------------------------

[ 本帖最后由 Frankman 于 2007-1-15 10:50 编辑 ]
Advertisement
Advertisement

2008年度奖章获得者

发表于 2007-1-15 10:51 |显示全部楼层
此文章由 jungle 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 jungle 所有!转贴必须注明作者、出处和本声明,并保持内容完整
我没有用过NHibernate,也不知道这个东西是干什么用的。

不过你得到的错误显然是由于试图在表中插入重复主键而引起,为什么你的delete会引起插入数据操作?

不过,你的主键看起来应该是复合主键 categoryid + productid ,都是 GUID 类型,是不是你的表主键定义错误,仅仅把categoryid设置为主键了?

发表于 2007-1-15 11:03 |显示全部楼层
此文章由 袁氏行 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 袁氏行 所有!转贴必须注明作者、出处和本声明,并保持内容完整
<list name="Products"
          table="EBS_C_Category_Product"
          lazy="false"
          cascade="save-update">
      <key column="CategoryId"/>
      <index column="DisplayOrder"/>
      <many-to-many class="EBSimple.Commerce.DomainModel.Product, EBSimple.Commerce.DomainModel" column="ProductId"/>
    </list>

You only define the  CategoryId as primary Key, it should be composite primary key (categoryId + productId) according to what you described here.

发表于 2007-1-15 11:09 |显示全部楼层
此文章由 Frankman 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Frankman 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 jungle 于 2007-1-15 11:51 发表
我没有用过NHibernate,也不知道这个东西是干什么用的。

不过你得到的错误显然是由于试图在表中插入重复主键而引起,为什么你的delete会引起插入数据操作?

不过,你的主键看起来应该是复合主键 categoryid ...

thanks for your message. The primary key is composite one which includes both Ids.

发表于 2007-1-15 11:17 |显示全部楼层
此文章由 Frankman 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Frankman 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 袁氏行 于 2007-1-15 12:03 发表
<list name="Products"
          table="EBS_C_Category_Product"
          lazy="false"
          cascade="save-update">
      <key column=&qu ...


thanks a lot for coment.

This "key" is not a primary key in database table. It tells Hibernate how to generate " Products" property of Category class. In my case, it instructs NHibernate to use CategoryId, which makes sense because one category can have multiple products. The mapping file is  correct. At this stage, I suspect this error is caused by a bug in NHibernate itself. I mean indexed collection is not ported over properly from Hibernate 2.1.7. Stragne enough, nobody from Nhibernate team confirms this, which makes my life like hell.

[ 本帖最后由 Frankman 于 2007-1-15 12:27 编辑 ]

发表于 2007-1-15 11:43 |显示全部楼层
此文章由 北风 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 北风 所有!转贴必须注明作者、出处和本声明,并保持内容完整
看cmd内容先
Advertisement
Advertisement

2008年度奖章获得者

发表于 2007-1-15 11:49 |显示全部楼层
此文章由 jungle 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 jungle 所有!转贴必须注明作者、出处和本声明,并保持内容完整
刚刚google了一下,才发现原来NHibernate 也是一个用作Data Access Layer的第三方工具。

TNND,不知道这些澳洲人怎么那么喜欢用这些数据库对象化的工具。我们公司用的是LGEN,我觉得也有不少毛病。它的事务控制机制就让我总觉得不能彻底相信,现在仍然有时候会出现同一个事务内的动作部分成功的情况。

我只能猜:也许是你的这个NHibernate 对composite primary key 的支持本身有问题。你不如再加一个列category_product_id来做PK,那两个列只用作FK。

发表于 2007-1-16 09:45 |显示全部楼层
此文章由 Frankman 原创或转贴,不代表本站立场和观点,版权归 oursteps.com.au 和作者 Frankman 所有!转贴必须注明作者、出处和本声明,并保持内容完整
原帖由 jungle 于 2007-1-15 12:49 发表
刚刚google了一下,才发现原来NHibernate 也是一个用作Data Access Layer的第三方工具。

TNND,不知道这些澳洲人怎么那么喜欢用这些数据库对象化的工具。我们公司用的是LGEN,我觉得也有不少毛病。它的事务控制 ...

It wouldn't make any difference. It used to work without index column (two bags mapping). Pretty sure it's caused by NHibernate itself. It seems to me that Indexed column only works in Hibernate 3.

Hibernate is not only a tool. It includes many data access best practices and even goes further. It's so popular in Java community and the same concept is getting more and more attention in .NET world. Have a look at DLINQ project at Microsoft and you will know what I mean, although it's crippled implementaiton of ORM.

发表回复

您需要登录后才可以回帖 登录 | 注册

本版积分规则

Advertisement
Advertisement
返回顶部