NHibernate problem with assigned string id and various case characters

I have a problem saving an object with an assigned Id string in NHibernate ... I'm trying to explain a problem with an example.

Well, suppose you have an entity in the database with the identifier "AAA" if I execute these statements

ENTITYTYPE entity = Session.Get<ENTITYTYPE>("AAA"); ENTITYTYPE newentity = new ENTITYTYPE() { Id = "aaa" }; Session.Delete(entity); Session.Save(newentity); Session.Flush(); 

Flush NHibernate throws an exception with this message: "Failed to sync database state with session" / "Primary key violation"

There seems to be a problem with Case Sensitive ID, if I use β€œAAA” on the β€œnewbie” identifier then it works, but in my situation it is not so simple and I have to find an alternative solution.

How to avoid this exception? Can you help me?

+3
source share
1 answer

I don't know if this is enough, but you manage it with something like this:

 public override bool Equals(object obj) { T other = obj as T; if (other == null) return false; // handle the case of comparing two NEW objects bool otherIsTransient = Equals(other.Id, Guid.Empty); bool thisIsTransient = Equals(Id, Guid.Empty); if (otherIsTransient && thisIsTransient) return ReferenceEquals(other, this); return other.Id.ToUpper().Equals(Id.ToUpper()); } 

using the ToUpper () or ToLower () method while comparing your object, or you can use String.Compare (stringA, strngB, StringComparison.OrdinalIgnoreCase).

If you need more control, and if that is your goal, you can create your own Id generator, as described here:

http://nhibernate.info/doc/howto/various/creating-a-custom-id-generator-for-nhibernate.html

updated

Have you tried to create a custom GetIgnoreCase (...)?

I think it is also possible to override the default SELECT statement generated by the Get method in the entity mapping file using the loader tag, like this example:

  ... <loader query-ref="loadProducts"/> </class> <sql-query name="loadProducts"> <return alias="prod" class="Product" /> <![CDATA[ select ProductID as {prod.ProductID}, UnitPrice as {prod.UnitPrice}, ProductName as {pod.ProductName} from Products prod order by ProductID desc ]]> 

You can try changing the select statement that returns the uppercase identifier.

updated

After the investigation, I think that a way to solve your problem can be with Interceptor!

Read here:

http://knol.google.com/k/fabio-maulo/nhibernate-chapter-11-interceptors-and/1nr4enxv3dpeq/14#

more docs here:

http://blog.scooletz.com/2011/02/22/nhibernate-interceptor-magic-tricks-pt-5/

Something like that:

  public class TestInterceptor : EmptyInterceptor, IInterceptor { private readonly IInterceptor innerInterceptor; public TestInterceptor(IInterceptor innerInterceptor) { this.innerInterceptor = this.innerInterceptor ?? new EmptyInterceptor(); } public override object GetEntity(string entityName, object id) { if (id is string) id = id.ToString().ToUpper(); return this.innerInterceptor.GetEntity(entityName, id); } } 

and register it freely as follows:

 return Fluently.Configure() ... .ExposeConfiguration(c =>{c.Interceptor = new TestInterceptor(c.Interceptor ?? new EmptyInterceptor());}) ... .BuildConfiguration(); 
+2
source

Source: https://habr.com/ru/post/1387207/


All Articles