(Свободно) Проблема составного идентификатора NHibernate: MySQL жалуется, что индекс параметра выходит за пределы - PullRequest
1 голос
/ 10 января 2010

Я использую Fluent NHibernate для создания проекта ASP.NET MVC с представлениями и голосами (вверх / вниз) пользователями.

Конечно, пользователи могут голосовать за подачу вверх или вниз. Чтобы записать это, я создал промежуточную таблицу SubmissionVote, которая содержит следующие поля:

submissionId (int)
userId (int)
score (enum: up/down)

Вот мои отображения:

Представление

Id(x => x.Id);
...
References(x => x.User).Column("userID").Not.LazyLoad();
HasMany(x => x.Votes).Cascade.All().KeyColumn("submissionID").Table("SubmissionVote").Not.LazyLoad();
Table("Submission");

Пользователь

Id(x => x.Id);
...
HasMany(x => x.Submission).Inverse().KeyColumn("userID").Cascade.All();
HasMany(x => x.SubmissionVotes).KeyColumn("userID").Cascade.All().Table("SubmissionVote");

SubmissionVote

Map(x => x.Vote).Column("score");
CompositeId().KeyProperty(x => x.Submission.Id, "submissionID").KeyProperty(x => x.User.Id, "userID");
References(x => x.Submission).Column("submissionID");
References(x => x.User).Column("userID");

Так как средняя таблица в моей БД имеет поле оценки, я создал класс SubmissionVote для его представления. Поля пользователя и представления в этом классе являются отношениями «многие-к-одному» с их соответствующими классами.

Проблема заключается в следующем: класс SubmissionVote должен иметь свойство ID, в противном случае NHibernate выдает ошибку. Это не должно иметь место, так как идентификатор для SubmissionVote является составным идентификатором, как представлено в отображении.

Я могу жить с этим, но это вызывает другую проблему. Когда я пытаюсь сохранить представление с несколькими SubmissionVotes в нем, используя session.SaveOrUpdate (отправка), я получаю эту ошибку в виде исключения ArrayOutOfBounds, генерируемого MySQL, как в этом вопросе: Как я могу использовать составной идентификатор с класс как поле id в беглом nhibernate? .

Просматривая журналы NHibernate, я вижу запрос, отправляемый в MySQL.

14:53:07.358 [9] DEBUG ... - Building an IDbCommand object for the SqlString: INSERT INTO `SubmissionVote` (score, submissionID, userID) VALUES (?, ?, ?)
14:53:07.361 [9] DEBUG ... - binding 'Up' to parameter: 0
14:53:07.367 [9] DEBUG NHibernate.Type.Int32Type - binding '183' to parameter: 1
14:53:07.367 [9] DEBUG NHibernate.Engine.IdentifierValue - unsaved-value: 0
14:53:07.367 [9] DEBUG NHibernate.Type.Int32Type - binding '2' to parameter: 2
14:53:07.367 [9] DEBUG NHibernate.Type.Int32Type - binding '0' to parameter: 3

Очевидно, NHibernate пытается включить в запрос значение "ID" по умолчанию ('0') (вероятно, свойство ID, которое я добавил в SubmissionVote).

Связаны ли эти две проблемы? Как я могу решить эту проблему?

Большое спасибо!

Редактировать

Вот моя (частичная, но подходящая) схема, созданная NHibernate.

create table submission (
    Id INTEGER NOT NULL AUTO_INCREMENT,
   CreationDate DATETIME,
   BeginDate DATETIME,
   EndDate DATETIME,
   Content VARCHAR(255),
   userID INTEGER,
   primary key (Id)
)

create table User (
Id INTEGER NOT NULL AUTO_INCREMENT,
   UserName VARCHAR(255) unique,
   Password VARCHAR(255),
   Email VARCHAR(255),
   primary key (Id)
)

create table `submissionVote` (
submissionID INTEGER not null,
   userID INTEGER not null,
   score VARCHAR(255),
   primary key (submissionID, userID)
)

alter table `submissionVote` 
    add index (submissionID), 
    add constraint FKC2AE73C56C66D2D5 
foreign key (submissionID) 
references submission (Id)

alter table `submissionVote` 
add index (userID), 
add constraint FKC2AE73C5EC6C1277 
foreign key (userID) 
references User (Id)

alter table submission 
 add index (userID), 
 add constraint FKE6354599EC6C1277 
 foreign key (userID) 
 references User (Id)

1 Ответ

3 голосов
/ 12 января 2010

Я нашел решение! На самом деле, я должен был указать NHibernate, что составной идентификатор также является моей ссылкой.

Новые отображения выглядят так:

Map(x => x.Vote).Column("score");
CompositeId().KeyReference(x => x.Submission, "submissionID").KeyReference(x => x.User, "userID");
...