From: NHibernate J. <mik...@us...> - 2006-11-13 19:12:10
|
[ http://jira.nhibernate.org/browse/NH-343?page=all ] Sergey Koshcheyev closed NH-343: -------------------------------- Resolution: Won't Fix > Invalid database query generated for mappings with multiple references to a single column > ----------------------------------------------------------------------------------------- > > Key: NH-343 > URL: http://jira.nhibernate.org/browse/NH-343 > Project: NHibernate > Type: Improvement > Components: Core > Versions: beta-0.9 > Environment: SQL Server 2000 > Reporter: Orr Bernstein > Priority: Minor > > When a column appears multiple times in a mapping file, it's included in queries multiple times, yielding database errors. Example: > class A: > ... > <many-to-one name="X"> > <column name="a"/> > <column name="b"/> > </many-to-one> > <many-to-one name="Y"> > <column name="a"/> > <column name="c"/> > </many-to-one> > ... > class B: > <composite-id> > <key-property name="a"/> > <key-property name="z"/> > </composite-id> > ... > With SQL Server 2000, the error reported is: > NHibernate.ADOException: could not synchronize database state with session ---> > System.Data.SqlClient.SqlException: Column name 'XXXXXXX' appears more than once in the result column list. > Statement(s) could not be prepared. > at System.Data.SqlClient.SqlCommand.ExecuteReader(CommandBehavior cmdBehavior, RunBehavior runBehavior, Boolean returnStream) > at System.Data.SqlClient.SqlCommand.ExecuteNonQuery() > at NHibernate.Impl.BatcherImpl.ExecuteNonQuery(IDbCommand cmd) > at NHibernate.Impl.NonBatchingBatcher.AddToBatch(Int32 expectedRowCount) > at NHibernate.Persister.EntityPersister.Update(Object id, Object[] fields, Boolean[] includeProperty, Object oldVersion, Object obj, SqlString sqlUpdateString, ISessionImplementor session) > at NHibernate.Persister.EntityPersister.Update(Object id, Object[] fields, Int32[] dirtyFields, Object[] oldFields, Object oldVersion, Object obj, ISessionImplementor session) > at NHibernate.Impl.ScheduledUpdate.Execute() > at NHibernate.Impl.SessionImpl.ExecuteAll(IList list) > at NHibernate.Impl.SessionImpl.Execute() > --- End of inner exception stack trace --- > at NHibernate.Impl.SessionImpl.Execute() > at NHibernate.Impl.SessionImpl.Flush() > at NHibernate.Transaction.AdoTransaction.Commit() > at <application code> > (query is like: > UPDATE Table SET Column1=a, Column2=x, Column3=b, Column2=x, Column4=c WHERE PrimaryKey=d) > One possible solution is to allow this type of mapping, though an extra check done at the time that the query is produced, reducing the query above to include each column only once and throwing an exception if any of the separately provided values for that column are different than the others. One more constraint should be added as well - where the column is furthermore used as part or the whole of the primary key, a check should be done to ensure that none of the foreign-key uses of that column attempt to modify the value to something other than the value of that column in its primary key context. Finally, for sanity's sake, any primary key column should be removed from any modifying reference in the query (i.e. set pk_col1=...), which because of above-mentioned check wouldn't leave out any excepted changes to the row. > Or at very least, we oughta fix the "distinctColumns" bug for better error handling. I think it's a one-liner for beta-0.9 - insert at line 217 of Persister.EntityParser: > distinctColumns.AddAll( propertyColumnNames ); -- This message is automatically generated by JIRA. - If you think it was sent incorrectly contact one of the administrators: http://jira.nhibernate.org/secure/Administrators.jspa - For more information on JIRA, see: http://www.atlassian.com/software/jira |