Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Issues getting started #10

Closed
Meberem opened this issue Jun 12, 2019 · 5 comments
Closed

Issues getting started #10

Meberem opened this issue Jun 12, 2019 · 5 comments

Comments

@Meberem
Copy link

Meberem commented Jun 12, 2019

I am having some issues getting this up and running. I am using Fluent Hiberate to do my class mappings and I am unable to create a user table that lets me create a user. In my Startup.cs I have something that looks like this

services.AddSingleton(_ =>
            {
                var config = new Configuration().AddIdentityMappingsForSqlServer();
                return Fluently.Configure(config)
                    .Database(MsSqlConfiguration.MsSql2012.ConnectionString(
                        Configuration.GetConnectionString("MyDbConnection")))
                    .Mappings(m => { m.FluentMappings.AddFromAssemblyOf<Startup>(); })
                    .ExposeConfiguration(cfg =>
                    {
#if DEBUG
                        new SchemaUpdate(cfg).Execute(false, true);
#endif
                    })
                    .BuildConfiguration();
            });
            services.AddSingleton(sp => sp.GetRequiredService<Configuration>().BuildSessionFactory());
            services.AddScoped(provider => provider.GetService<ISessionFactory>().OpenSession());

and I have created an AppUser.cs like so

using System.Collections.Generic;
using NHibernate.AspNetCore.Identity;

namespace Api.Domain
{
    // Add profile data for application users by adding properties to the AppUser class
    public class AppUser : IdentityUser
    {
        // Properties to come late
    }
}

and a corresponding Map file

using Api.Domain;
using FluentNHibernate.Mapping;

namespace Api.Persistence.NHibernate
{
    public class AppUserMap : ClassMap<AppUser>
    {
        public AppUserMap()
        {
            Id(x => x.Id)
                .GeneratedBy.UuidHex("N");
            Map(x => x.AccessFailedCount);
            Map(x => x.ConcurrencyStamp).Length(32);
            Map(x => x.Email).Length(256);
            Map(x => x.NormalizedEmail).Length(256);
            Map(x => x.EmailConfirmed).Not.Nullable();
            Map(x => x.LockoutEnabled).Not.Nullable();
            Map(x => x.LockoutEnd);
            Map(x => x.PasswordHash).Length(256);
            Map(x => x.PhoneNumber).Length(128);
            Map(x => x.PhoneNumberConfirmed).Not.Nullable();
            Map(x => x.TwoFactorEnabled).Not.Nullable();
            Map(x => x.UserName)
                .Length(64)
                .Unique()
                .Not.Nullable();
            Map(x => x.NormalizedUserName)
                .Length(64)
                .Not.Nullable()
                .Unique();
            Map(x => x.SecurityStamp)
                .Length(64);
            Table("AspNetUsers");
        }
    }
}

which has come from here. When I attempt to use the UserManager to create a user I get the following in my debug log

dbug: NHibernate.SQL[0]
      Batch commands:
      command 0:INSERT INTO AspNetUsers (AccessFailedCount, ConcurrencyStamp, Email, NormalizedEmail, EmailConfirmed, LockoutEnabled, LockoutEnd, PasswordHash, PhoneNumber, PhoneNumberConfirmed, TwoFactorEnabled, UserName, NormalizedUserName, SecurityStamp, Id) VALUES (@p0, @p1, @p2, @p3, @p4, @p5, @p6, @p7, @p8, @p9, @p10, @p11, @p12, @p13, @p14);@p0 = 0 [Type: Int32 (0:0:0)], @p1 = '32de7879-d609-4a78-82ee-37650e454f5b' [Type: String (36:0:0)], @p2 = NULL [Type: String (4000:0:0)], @p3 = NULL [Type: String (4000:0:0)], @p4 = False [Type: Boolean (0:0:0)], @p5 = True [Type: Boolean (0:0:0)], @p6 = NULL [Type: DateTimeOffset (10:0:0)], @p7 = NULL [Type: String (4000:0:0)], @p8 = NULL [Type: String (4000:0:0)], @p9 = False [Type: Boolean (0:0:0)], @p10 = False [Type: Boolean (0:0:0)], @p11 = '754f8e5a7baf4e9fad97d2042ae63ad8' [Type: String (64:0:0)], @p12 = '754F8E5A7BAF4E9FAD97D2042AE63AD8' [Type: String (64:0:0)], @p13 = 'IMC5PYQMAD2NFKYPBG5DDE3O3V3BFBQ4' [Type: String (64:0:0)], @p14 = '8610930d5f9b48fcbfed5429c2390358' [Type: String (4000:0:0)]

dbug: NHibernate.Connection.DriverConnectionProvider[0]
      Obtaining DbConnection from Driver
dbug: NHibernate.Util.ADOExceptionReporter[0]
      could not execute batch command.
      [ SQL not available ]
      System.Data.SqlClient.SqlException (0x80131904): String or binary data would be truncated.
      The statement has been terminated.
         at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
         at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
         at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
         at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
         at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
         at System.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader()
         at System.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult)
         at System.Data.SqlClient.SqlCommand.EndExecuteNonQuery(IAsyncResult asyncResult)
         at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
      --- End of stack trace from previous location where exception was thrown ---
         at NHibernate.AdoNet.GenericBatchingBatcher.BatchingCommandSet.ExecuteNonQueryAsync(CancellationToken cancellationToken)
         at NHibernate.AdoNet.GenericBatchingBatcher.DoExecuteBatchAsync(DbCommand ps, CancellationToken cancellationToken)
      ClientConnectionId:e9f4ee77-797a-4e80-8a36-2c46af4ca461
      Error Number:8152,State:13,Class:16
System.Data.SqlClient.SqlException (0x80131904): String or binary data would be truncated.
The statement has been terminated.
   at System.Data.SqlClient.SqlConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection, Action`1 wrapCloseInAction)
   at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning(TdsParserStateObject stateObj, Boolean callerHasConnectionLock, Boolean asyncClose)
   at System.Data.SqlClient.TdsParser.TryRun(RunBehavior runBehavior, SqlCommand cmdHandler, SqlDataReader dataStream, BulkCopySimpleResultSet bulkCopyHandler, TdsParserStateObject stateObj, Boolean& dataReady)
   at System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds, RunBehavior runBehavior, String resetOptionsString)
   at System.Data.SqlClient.SqlCommand.CompleteAsyncExecuteReader()
   at System.Data.SqlClient.SqlCommand.EndExecuteNonQueryInternal(IAsyncResult asyncResult)
   at System.Data.SqlClient.SqlCommand.EndExecuteNonQuery(IAsyncResult asyncResult)
   at System.Threading.Tasks.TaskFactory`1.FromAsyncCoreLogic(IAsyncResult iar, Func`2 endFunction, Action`1 endAction, Task`1 promise, Boolean requiresSynchronization)
--- End of stack trace from previous location where exception was thrown ---
   at NHibernate.AdoNet.GenericBatchingBatcher.BatchingCommandSet.ExecuteNonQueryAsync(CancellationToken cancellationToken)
   at NHibernate.AdoNet.GenericBatchingBatcher.DoExecuteBatchAsync(DbCommand ps, CancellationToken cancellationToken)
ClientConnectionId:e9f4ee77-797a-4e80-8a36-2c46af4ca461

What can I do to fix this? Also is there a better way of adding the mappings for my AppUser?

@beginor
Copy link
Member

beginor commented Jun 12, 2019

System.Data.SqlClient.SqlException (0x80131904): String or binary data would be truncated.

Please check the length of your columns, this exception is usually caused by the length of content exceeds the column's length definition.

And since you have called AddIdentityMappingsForSqlServer , AppUser should be mapped as joined-subclass, please check the mapping file AppUser.hbm.xml in the WebTest project, I think Fluent Hiberate can do joined subclass mapping too.

Please use the sql scripts in the database folder to create your identity tables, because it is more accurate then the SchemaUpdate .

@Meberem
Copy link
Author

Meberem commented Jun 13, 2019

Thanks for your reply. Strangely I was able to run the SQL statement manually, not entirely sure what was going on there. I have tried to add AppUser as a SubClassMap but it appears it is not picked up properly. Looking into it, based on this issue I don't think that is possible to have a joined-subclass in Fluent Hiberate when the base is in an xml file. What would your advice be for this? With my very limited knowledge of NHiberate I think I have 2 options:

  • Create FluentMappings based of the AppUser.hbm.xml
  • Don't use FluentHiberate and create my own *.hbm.xml

@beginor
Copy link
Member

beginor commented Jun 14, 2019

I have seen the issue, it seems joined-subclass mapping is not supported by FluentNHibernate know. But you have 3 options:

  1. Create all mappings for all classes, include NHibernate.AspNetCore.Identity 's classes , please refer to the exists hbm mappings;
  2. Just use *.hbm.xml files , don't use FluentHiberate;
  3. Use NHibernate.Mapping.Attributes, it support joined-subclass mapping with the existing hbm xml mapping , which I have tested with it before。

Personaly, I prefer to use xml mapping (*.hbm.xml), because both FluentHiberate and NHibernate.Mapping.Attributes will translate it's mapping to xml mapping at runtime. And with the help of NHibernate's xml schema (nhibernate-configuration.xsd and nhibernate-mapping.xsd) file, editing hbm file with intelli popup is easy too.

@Meberem
Copy link
Author

Meberem commented Jun 18, 2019

Thanks for your thoughts and insights on this, it has been very helpful!

@beginor
Copy link
Member

beginor commented Jun 18, 2019

you are welcome. If there is nothing else, I think this issue can be closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants