2011-11-09 4 views
1

У меня возникла очень странная проблема (я должен делать что-то неправильно, просто не могу найти свои ошибки!). Когда определенные базы данных сохраняются в базе данных, ничего не происходит. Когда те же POCOs меняют какое-то свойство, я получаю InvalidCastException во время сеанса flush, и строки никогда не обновляются. Вот подробности:Обновление объекта с помощью nhibernate throws InvalidCastException (но его не сохраняет)

я следующий класс заявил:

namespace Data 
{ 
    public class Picture 
    { 
     public virtual int picid { get; set; } 
     public virtual int width { get; set; } 
     public virtual int height { get; set; } 
     public virtual string path { get; set; } 
     public virtual string thumbnail { get; set; } 
     public virtual int userid { get; set; } 
     public virtual int? placeid { get; set; } 
     public virtual int? eventid { get; set; } 
     public virtual DateTime? approved { get; set; } 
     public virtual DateTime date { get; set; } 
     public virtual bool finished { get; set; } 

     public virtual User User { get; set; } 
     public virtual Place Place { get; set; } 
     public virtual Event Event { get; set; } 

     public virtual ISet<PictureVote> Votes { get; set; } 
    } 

}

и следующее отображение для него:

<?xml version="1.0" encoding="utf-8" ?> 
<hibernate-mapping xmlns="urn:nhibernate-mapping-2.2" assembly="Data" namespace="Data"> 
    <class name="Picture" table="pictures"> 
    <id name="picid"> 
     <generator class="sequence"> 
      <param name="sequence">pictures_picid_seq</param> 
     </generator> 
    </id> 
    <property name="path" /> 
    <property name="width" /> 
    <property name="height" /> 
    <property name="thumbnail" /> 
    <property name="userid" /> 
    <property name="placeid" not-null="false" /> 
    <property name="eventid" not-null="false" /> 
    <property name="approved" /> 
    <property name="date" /> 
    <property name="finished" /> 

    <many-to-one name="User" column="userid" class="Data.User,Data" insert="false" /> 
    <many-to-one name="Place" column="placeid" class="Data.Place,Data" insert="false" /> 
    <many-to-one name="Event" column="eventid" class="Data.Event,Data" insert="false" /> 
    <set name="Votes"> 
     <key column="picid" /> 
     <one-to-many class="PictureVote" /> 
    </set> 
    </class> 

</hibernate-mapping> 

Я проверил определение таблицы и все типы по-видимому, соответствуют определенному классу (postgresql):

         Table "public.pictures" 
    Column |   Type    |      Modifiers       
-----------+-----------------------------+---------------------------------------------------------- 
picid  | integer      | not null default nextval('pictures_picid_seq'::regclass) 
path  | character varying(250)  | not null 
thumbnail | character varying(250)  | not null 
userid | integer      | not null 
placeid | integer      | 
date  | timestamp without time zone | not null 
finished | boolean      | not null default false 
width  | integer      | not null 
height | integer      | not null 
eventid | integer      | 
approved | timestamp without time zone | 

Когда внутри кода, следующие работы просто отлично и вставляет строку в таблицу картинки: ... ...

var plpic = new Picture 
       { 
        date = DateTime.Now, 
        width = img.Width, 
        height = img.Height, 
        path = pic_server_path, 
        thumbnail = thumb_server_path, 
        userid = CustomUserManagement.User.userid, 
        finished = false, 
        approved = null, 
        placeid = placeid 
       }; 
       session.Save(plpic); 
       session.Flush(); 

... ... , который хорошо работает каждый раз, когда (и да, я собираюсь обернуть его в транзакции достаточно скоро).

Однако позже, следующее никогда не работает (это код внутри действия MVC): ... ...

Picture pic = session.Get<Picture>(picid); 
      // While debugging, I verified that the "pic" object above is retrieved just fine. 
      if (pic.userid != CustomUserManagement.User.userid || ModelState.IsValid == false) 
       return Json (new { status = "error" }); 

      using (ITransaction tx = session.BeginTransaction()) { 
       try 
      { 
       pic.finished = true; 

       tx.Commit(); 
      } 
      catch (Exception e) { 
       tx.Rollback(); 
       NHibernateHelper.DestroySession(); 

       return Json (new { status = "error" }); 
      } 
     } 

... ... Но это всегда бросает System.InvalidCastException: не может отбрасываться из типа источника в тип назначения в NpgsqlTypes.NpgsqlTypesHelper + c_ Iterator11. <> м _C (System.Object метка времени) [0x00000] в /Users/fxjr/Desenvolvimento/ProjetosOpenSource/Npgsql/NpgsqlSourceRelease/Npgsql2/src/NpgsqlTypes/NpgsqlTypesHelper.cs:608

Что я делаю неправильно? Я использую .NET 4 в Mono 2.10.5, хотя это происходит и в Windows, NHibernate 3.2 и Npgsql 2.0.11.91. Я также использую postgresql 9.1.1, но я установил ansi_conforming_strings в OFF, чтобы убедиться, что мой диалект Nhibernate все еще работает. Для получения дополнительной информации, то же самое происходит при обновлении других типов объектов.

Я уже опубликовал это в списке nhusers и получил очень хорошее предложение по попытке другого db проверить, не является ли это его ошибкой Npgsql. Тем не менее, у меня нет времени на это прямо сейчас, и поскольку я начинаю думать, что это моя вина, а не кто-то другой, я думал, что разместил это здесь, прежде чем воссоздать мою схему db в другой базе данных и попробовать этот код в этом. Я становлюсь немного отчаянным, поскольку время от меня заканчивается ... может ли кто-нибудь спасти меня на этом?

Заранее спасибо.

+0

Я не уверен, если вы все еще невежественны, тогда вы можете попытаться получить объект pic внутри транзакции. получить объект внутри транзакции, если условие истинно, затем обновить объект и зафиксировать. – Zohaib

+0

Просто попробовал, и это, и никакого успеха, было исключено одно и то же исключение. Любые другие идеи? –

+0

Не могли бы вы попытаться с предыдущей версией Npgsql? Я думаю, вы должны попробовать даже в 2.0.10. Я почти уверен, что это ошибка в самом Npgsql. Если вы можете создать консольное воспроизведение этой ошибки, я был бы очень рад, поэтому мы сможем исправить эту проблему. Заранее спасибо. –

ответ

3

После долгого времени, я думал, что должен вернуться сюда, чтобы ответить на мой собственный вопрос.
Это не обязательно ошибка в NHibernate или Npgsql.
Я делал огромную ошибку в файлах сопоставления, дважды сопоставляя один и тот же столбец. Это означает, что наличие int? eventid и Event Event в моем сопоставленном классе и карта в тот же столбец создаст вам проблемы, поскольку NHibernate не может справиться с этим, то есть вам нужно выбрать один из них.Что происходит, так это то, что NHibernate будет генерировать запросы с большим количеством параметров, чем фактическое количество столбцов в вашей таблице. В MS SQL Server, то проще понять, выброшенное исключение:

Недопустимый индекс N для этого SqlParameterCollection с Count = N

Другой альтернативой является отображение обоих, но установка вставки = «ложных» и обновления = «false» в одном из них, хотя это вряд ли полезно.
Я думаю, что многие такие люди, как я (из LINQ-TO-SQL), будут пытаться выполнить тот же подвиг, и у вас будет много проблем позже. К сожалению, я не нашел ничего, что подчеркивает это в документации NHibernate.

Надеюсь, это поможет кому-то.

 Смежные вопросы

  • Нет связанных вопросов^_^