NHibernate Evict - EntityKeys is readonly so object won't evict - nhibernate

A vendor supplied code using NHibernate... and I'm not familiar at all with NHibernate. At one point in the code, it is calling the Flush() and it is throwing an error because one of the entities has a 1/1/0001 for a date value. I attempted to circumvent by evicting any entities that have that as a value. However, the evict is not working as the EntityKeys is set to Read-Only.
Code:
if (((Event)e.Identifier).EnrollmentDate == DateTime.MinValue)
{
Db.CurrentSession.Evict(e.Identifier);
}
I also attempted:
Db.CurrentSession.Evict(typeof(Event));
Whenever the code executed, it didn't throw any errors, but it didn't evict either. When I tried the RemoveAt, it threw the 'Collection is read-only.' error
Is there a way around that?

You need to fix the problem with the date being set to an invalid value. Attempting to work around the problem is a losing proposition.

Related

Unable to observe an array of objects (mobx)

According to the docs: https://mobx.js.org/refguide/array.html
I should be able to observe an array.
observe(listener, fireImmediately? = false) Listen to changes in this
array. The callback will receive arguments that express an array
splice or array change, conforming to ES7 proposal. It returns a
disposer function to stop the listener.
However I'm getting an exception when I do so within my app:
core.js:1350 ERROR Error: Uncaught (in promise): Error: [mobx] Cannot obtain administration from Neil Clayton,Ralph Lambert,Suzie Legg
at invariant (mobx.module.js:2652)
at fail$1 (mobx.module.js:2647)
at getAdministration (mobx.module.js:1967)
at observeObservable (mobx.module.js:3606)
at observe (mobx.module.js:3603)
at ObjectChangeTracker.webpackJsonp.683.ObjectChangeTracker.installObserverDirectlyOn (orm-change-detection.ts:258)
I'm unsure why getAdministration() is falling through.
I was under the impression I could pass anything into observe() (either a JS Object, real class or array thereof).
Am I mistaken that I can observe an array?
It turns out I was trying to observe a direct 'Array'.
This was happening because I was iterating the parent object keys, and getting the values by doing parent[propertyName]. Where 'propertyName' is provided by some other object (i'm intentionally leaving out specifics so as to not complicate my answer).
This was a couple of days ago now, but from memory this caused access via a getter, which had a side effect (returned a sorted array, new object, that wasn't observable).
If instead I got the value by the private field directly, and then observed the actual ObservableArray, my problems disappeared.
So, no longer convinced my question is valid.
Code is here: https://github.com/scornflake/scheduler
(but not expecting anyone to take a look, it's reasonably convoluted at the moment)

Talend - NullPointer in BigDecimal.add()

I'm having an error on my Job when I do adding of BigDecimal on my tMap.
this is my code.
Var.var1.add(Var.var2).add(Var.var3).add(Var.var4)
all of my variables are BigDecimal.
my error is 'NullPointerException'.
I already checked data on my Database and all have values. I also checked Nullable on my tMap.
Thank You.
This error is happening because you are calling uninitialized variables.
Maybe you are writing this sentence inside the Var box in the tMap?
If not, are you able to output all the Var.varN BigDecimals independently without errors?

Getting NHibernate to report mapping problems

So I've been doing some work with NHibernate, and while what I have seen is mostly great, one thing is a little frustrating. If I try to query for some objects and there is a mapping problem in or with the hbm file, often there is no indication that there is a mapping problem, it just returns no results.
A simple example is if I forget to set the hbm file as an embedded resource, and then do a session.Query<Variable>().ToList(), there is no indication that there is no mapping for Variable, it just returns an empty list.
Is there any way to tell NHibernate to throw an exception or otherwise indicate that there is a problem with the mapping(s) in situations like this?
This does result in an exception:
_session.Get<Variable>(1)
But these do not:
_session.Query<Variable>().Where(e => e.VariableId == 1).ToList()
_session.CreateCriteria(typeof(Variable)).Add(Restrictions.Eq("VariableId",1)).List<Variable>();
Hopefully it's something that I'm doing wrong, or something that can be configured, otherwise it will probably be a deal-breaker for using NHibernate. I can catch these things in my own unit tests relatively easy, but I can just see this becoming a festival of bugs when other developers start touching it.
After doing a bit of digging through the code, I suspect you are right. Unmapped classes don't throw an exception on a List.
https://github.com/nhibernate/nhibernate-core/blob/master/src/NHibernate/Impl/SessionImpl.cs#L1869
string[] implementors = Factory.GetImplementors(criteria.EntityOrClassName);
int size = implementors.Length;
CriteriaLoader[] loaders = new CriteriaLoader[size];
ISet<string> spaces = new HashSet<string>();
for (int i = 0; i < size; i++)
{
loaders[i] = new CriteriaLoader(
GetOuterJoinLoadable(implementors[i]),
Factory,
criteria,
implementors[i],
enabledFilters
);
spaces.UnionWith(loaders[i].QuerySpaces);
}
Note how if there are no implementors that are returned by Factory.GetImplementors, no error is generated, but nothing is done. Hence why you are seeing an empty list come back.
If we look at SessionFactoryImpl.GetImplementors we see that at no point is an exception thrown if no implementor is found. Just an empty array of implementors is returned.
So potentially there needs to be a check that if no implementors are returned by Factory.GetImplementors, a MappingException needs to be thrown.

LINQ to Entities does not recognize the method [Type] GetValue[Type]

I've a simple class like this:
Public Class CalculationParameter{
public Long TariffId{get;set;}
}
In a workflow activity, I've an Assign like this:
(From tariffDetail In db.Context.TariffDetails
Where tariffDetial.TariffId = calculationParameter.TariffId).FirstOrDefault()
Dto is passed to Activity as an Input Argument.
It raise following error and I'm wondering how to assign Id. Any Idea?
LINQ to Entities does not recognize the method 'Int64
GetValue[Int64](System.Activities.LocationReference)' method, and this
method cannot be translated into a store expression.
How can I assign the calculationParameter.TariffId to tariffDetial.TariffId?!
UPDATE:
Screen shot attached shows that how I'm trying to assign calculationParameter.TariffId to tariffDetail.TariffId (car.Id = Dto.Id) and the query result should assign to CurrentTrafficDetail object.
Here's your problem. I don't know if there is a solution to it.
As you said in a (now deleted, unfortunately necessitating that I answer) comment, the exception you're getting is
LINQ to Entities does not recognize the method Int64 GetValue[Int64](System.Activities.LocationReference) method, and this method cannot be translated into a store expression.
in your Linq query, calculationParameter is a Variable defined on the workflow. That Variable is actually an instance that extends the type System.Activities.LocationReference and NOT CalculationParameter.
Normally, when the workflow executes, the LocationReference holds all the information it needs to find the value which is assigned to it. That value isn't retrieved until the last possible moment. At runtime, the process of retrieval (getting the executing context, getting the value, converting it to the expected type) is managed by the workflow.
However, when you introduce Linq into the mix, we have the issue you are experiencing. As you may or may not know, your expression gets compiled into the extension method version of the same.
(From tariffDetail In db.Context.TariffDetails
Where tariffDetial.TariffId = calculationParameter.TariffId)
.FirstOrDefault()
is compiled to
db.Context.TariffDetails
.Where(x => x.TariffId = calculationParameter.TariffId)
.FirstOrDefault();
When this executes, L2E doesn't actually execute this code. It gets interpreted and converted into a SQL query which is executed against the database.
As the interpreter isn't omniscient, there are a well defined set of limitations on what methods you can use in a L2S query.
Unfortunately for you, getting the current value of a LocationReference is not one of them.
TL:DR You cannot do this.
As for workarounds, the only thing I think you can do is create a series of extension methods on your data context type or add methods to your CalculationParameter class that you can call from within the Expression Editor. You can create your Linq to Entities queries within these methods, as all types will already have been dereferenced by the workflow runtime, which means you won't have to worry about the L2E interpreter choking on LocationReferences.
*Edit: A workaround can be found here (thanks to Slauma who mentioned this in a comment on the question)

Linq Update Problem

I'm having some problems updating the database using Linq...
Public Shared Function Save(ByRef appointment As MyLinq.Appointment, ByRef db As MyEntities) As Boolean
If appointment.id = 0 Then
db.AddToAppointments(appointment)
Else
db.AttachTo("Appointments", appointment)
'db.ApplyPropertyChanges("Appointments", appointment)
End If
Return db.SaveChanges() > 0
End Function
So Insert works fine, i have tryed both lines of code for the update with no sucesss... The first one goes ok but no update is performed, the second one throws an exception...
Can someone point out what i am missing?
EDIT:
Sorry for the late reply... I had some internet connection problems...
I had to "make it work", so now my update code is fecthing the record from the database, updating and then executing "SaveChanges" method. It works but I am not happy having to query the database to perform an Update... If you have any idea how I could do this without an update I would appreciate :)
Chris: It was a nice try, but my refresh method only allows me to choose "RefreshMode.ClientWins" or "RefreshMode.StoreWins" I tried with ClientWins with no success...
Razzie: I am sorry but i did not save the exception and it no longer occurs... It was saying that my record did not have a key associated (or something similar)
Jon Skeet: In Vb.Net we have to specify if the parameter goes ByVal or ByRef, we can't omit like in C#
The code you have doesn't look exactly like what I'm used to (linq to sql), but it does look a little similar; Is this Entity Framework?
I know with Linq to SQL, simply attaching an object to the data context isn't enough, you also have to make sure that the data context knows what the original values are so it knows which columns to update. In Linq to SQL that can be achieved like this:
db.Refresh(RefreshMode.KeepCurrentValues, appointment)
Maybe look around and see if you can achieve something similar in whatever framework you are using.
The ApplyPropertyChanges() call is important otherwise the item you are attaching is assumed to be in an unchanged state. However... for ApplyPropertyChanges to work properly the original object must exist in the ObjectContext which means either querying for it again (which I think you are now doing) or using the same object context that you originally pulled the item from.
Some more info here - http://msdn.microsoft.com/en-us/library/system.data.objects.objectcontext.applypropertychanges.aspx