The error “Table {Project.DbName}.hibernate_unique_key doesn’t exist” appear after trying to add a record in a newly created Sharp Architecture project using NHibernate map to MySql database server. The database and tables that I was using to add a record from my view existed and were configured correctly. The table had a unique key (“Id”) set to “not null”, “autoincrement” and “Primary Key”.
After running the code generator (CrudScaffolding project) I ended up with a Core class for my entity (‘User‘ in my case), test class, controller and view pages to perform CRUD operations. The error appeared after I was trying to add a new User using the newly created ADD page and clicked “Save User”.
The solution in my case was simple enough. Sharp MVC Architecture is already wired to use NHibernate and Fluent NHibernate to map the entities to their corresponding database tables. As you can read in the “NHibernate.config” file, Fluent NHibernate is set up in Global.asax.
By default your Fluent NHibernate set up in Global.asax will look like this:
All the wiring is there. But what was missing was the mapping class. So I wrote a mapping class ‘UserMap‘ to test my mapping for ‘User‘ class in {MyProjectName}.Data.NHibernateMaps
After adding the mapping class I rebuilt the project and try to Save a New User again and this time everything was fine. No errors and a New User was created successfully.
KS
Thanks for this info. It really helped me a lot.
If it’s not stretching the friendship, could you possibly show an example of how you create a mapping class where one entity has a field that is mapped to another entity?
To use your example as a starting point, suppose you had a “UserTypeFk” field in the User class that mapped to another class “UserType”.
How would you write the “UserMap” mapping class to accommodate that?
DaCoder
Sorry for the delay KS. I am involved almost 90% on this new project. I actually got this code below from the project I am currently working on. This ‘User’ class needs a reference to MembershipPlan entity so we can associate each user with the kind of membership that he/she currently holds (for now, is only PAID and FREE). I hope this helps.
public class UserMap : IAutoMappingOverride
{
public void Override(AutoMap mapping)
{
mapping.WithTable("Users");
mapping.Id(x => x.Id, "UserId")
.WithUnsavedValue("00000000-0000-0000-0000-000000000000")
.GeneratedBy.GuidComb();
mapping.Map(x => x.UserName, "userName").Not.Nullable().WithLengthOf(50);
mapping.Map(x => x.Email, "email").Not.Nullable().WithLengthOf(40);
mapping.Map(x => x.FirstName, "firstName").WithLengthOf(50);
mapping.Map(x => x.LastName, "lastName").WithLengthOf(80);
mapping.Map(x => x.RegistrationDate, "registrationDate");
mapping.Map(x => x.UpdatedBy, "updatedBy");
mapping.Map(x => x.UpdatedByDate, "updatedByDate");
mapping.Map(x => x.LastLogon, "lastLogon");
mapping.References(x => x.MembershipPlan, "PlanId").LazyLoad().Cascade.None();
}
}
Galen Parker
bless you mate, this was doing my head in. Trying to learn SharpArch and could not find an answer to this exact problem anywhere. Very grateful.
DaCoder
Excellent!!! I am glad this posts are helping other developers. Thanks a lot for your comment.
DaCoder
I will definitely will have to take a look at this much cleaner way to fix the issue. Thanks for the help David.