Linq ChangeConflictException occurs when submitting DataContext changes - linq-to-sql

System.Data.Linq.ChangeConflictException: 2 of X updates failed.
at System.Data.Linq.ChangeProcessor.SubmitChanges(ConflictMode failureMode)
at System.Data.Linq.DataContext.SubmitChanges(ConflictMode failureMode)
at PROJECT.Controllers.HomeController.ClickProc(Int32 id, String code, String n)
This is what I get very often. This action is done thousands of times a day, and I get this exception about once every 5 seconds. From what I understand it happens when something changes in the database in the period between creating DataContext and updating it. Am I right?
How can I fix it?
Update
I just debugged the error and found the following:
Table name: dbo.Stats
current value: 9852039
original value: 9852038
database value: 9852039
The Stats table is updated constantly. So how can I still make LINQ save the changes. With "classical" SQL Server access through SqlDataCommand I never had problems like that.

This is due to optimistic concurrency. You can change this behavior but understand what it does before you do it.
https://blogs.msdn.microsoft.com/matt/2008/05/22/intro-to-linq-to-sql-optimistic-concurrency/

Related

Do views immediately reflect data changes in their underlying tables?

I have a view ObjectDisplay that is composed of two relevant tables: Object and State. State represents the state of an Object, and the view pulls some of the details from the most recent State for each Object.
On the page that is displaying this information, a user can enter some comments, which creates a new State. After creating the new State, I immediately pull the Object from ObjectDisplay and send it back to be dropped into a partial view and replace the Object in the grid on the page.
// Add new State.
db.States.Add(new State()
{
ObjectId = objectId,
Comments = comments,
UserName = username
});
// Save the changes (executes all of the above).
db.SaveChanges();
// Return the new Object information.
return db.Objects.Single(c => c.ObjectId == objectId);
According to my db trace, the Single call occurs about 70 ms after the SaveChanges call, and it occurs on the same SPID.
Now for the issue: The database defaults the value of RecordDate in State to GETUTCDATE() - I don't provide the date myself. What I'm seeing is that the Object returned has the State's RecordDate of the old State and the Comments of the new State information of the old State. I am seeing that the Object returned has the old State's information. When I refresh the page, all the correct information is there, but the wrong information is returned in the initial call from the database/EF.
So.. what could be wrong? Could the view not be updating quickly enough? Could something be going on with EF? I don't really know where to start looking.
If you've previously loaded the same Object entity in the same DbContext, EF will return the cached instance with the stale values, and ignore the values returned from SQL.
The simplest solution is to reload the entity before returning it:
var result = db.Objects.Single(c => c.ObjectId == objectId);
db.Entry(result).Reload();
return result;
This is indeed odd. In SQL Server views are not persisted by default and therefore show changes in the underlying data right away. You can create a clustered index on a view with effectively persists the query, but in that case the data is updated synchronously, so you should see the change right away.
If you are working with snapshot isolation level your changes might not be visible to other SPIDs right away, but as you are on the same SPID and do not use snapshot isolation, this cant be the culprit either.
The only thing left at this point is the application layer. Are you actually using the result of the Single call higher up in the call stack or does that get lost somewhere. I assume that a refresh of the page uses a different code path, which would explain why it is working there.

How to get hibernate to store a date?

I have a Spring / Hibernate project and I am trying to store a date into the database but it's not working. It must be something stupid but I have no idea what I am doing wrong.
Here is my code:
user.setFailedPasswordAnswerAttemptCount(0);
user.setLastLoginDate(new Date());
user.setIsOnline(true);
The other two variables (failedPasswordAnswerAttemptCount and isOnline) are getting written to the database without issue. I have also tried it with just passing a java.util.Date instead of a java.sql.Timestamp...same result. Here is how the property is defined on the user object:
private Date lastLoginDate;
#Temporal(TemporalType.TIMESTAMP)
#Column(name="last_login_date")
public Date getLastLoginDate() {
return this.lastLoginDate;
}
public void setLastLoginDate(Date lastLoginDate) {
this.lastLoginDate = lastLoginDate;
}
Here is the column definition:
`last_login_date` datetime DEFAULT NULL
Any help? I don't even know what else to look for as this should be working.
Some more detail about the error: No errors or strange messages in the hibernate log. The hibernate log is showing a parameterized query but it isn't telling me what it is actually writing. It looks like it's not updating the column at all. In other words, if there is already a date there it doesn't change, or if it is null it doesn't change.
Update: I have looked at the logs and it looks like hibernate does write the proper data, but then immediately writes the incorrect data again. I see the following entry in the log:
11:15:12.280 [http-bio-8080-exec-26] TRACE o.h.e.def.AbstractSaveEventListener - detached instance of: com.hi.model.User
11:15:12.280 [http-bio-8080-exec-26] TRACE o.h.e.def.DefaultMergeEventListener - merging detached instance
And right after that I see it putting the old value back in for the lastLoginDate.
Why are you using
Date date = new Date();
user.setLastLoginDate(new Timestamp(date.getTime()));
and not just this?
user.setLastLoginDate(new Date());
First - You may not want to use Date and Timestamp at the same time.(e.g. for collections, etc)
There are some classes in the Java platform libraries that do extend an instantiable
class and add a value component. For example, java.sql.Timestamp
extends java.util.Date and adds a nanoseconds field. The equals implementation
for Timestamp does violate symmetry and can cause erratic behavior if
Timestamp and Date objects are used in the same collection or are otherwise intermixed.
The Timestamp class has a disclaimer cautioning programmers against
mixing dates and timestamps. While you won’t get into trouble as long as you
keep them separate, there’s nothing to prevent you from mixing them, and the
resulting errors can be hard to debug. This behavior of the Timestamp class was a
mistake and should not be emulated. (Bloch, Effective Java, 2nd Ed.)
Second - I checked your examples, and it works fine for me on mysql-connector(5.1.21) / hibernate (4.0.1)
I prepared simple test project with arquillian integration test(You need to prepare jboss before running it):
https://github.com/rchukh/StackOverflowTests/tree/master/13803848
If you can provide some more information it might help - hibernate version, mysql version, mysql engine(MyISAM, InnoDB, etc.)
Otherwise it is possible that this is just a misconfiguration.
I found the problem. I am refactoring some code and it looks like I was doing this:
//get user object
User user = getUser();
//call a function which modifies user
functionModifiesUser();
//modify user
user.blah = blah;
entityManager.merge(user);
So the parent function had a stale copy of the user object when I tried to save it. Actually, removing the merge statement was enough to fix it. But I have refactored the code to put all this in one place.
Setting the column last_login_date as timestamp should work, at least works for me.

Linq to SQL "Cannot insert the value NULL" when NOT NULL!

I am massively in need to help. I have spent an entire day when I do not have even an hour to waste on a project. I have a Linq to SQL data layer and am doing a simple insert into the DB using the following code:
using (var odc = new OrdersDataContext())
{
try
{
var id = GetNextOrderId(odc);
order.ID = id;
odc.tblOrders.InsertOnSubmit(order);
odc.SubmitChanges();
}
catch (Exception ex)
{
Logger.LogException(ex);
}
}
Due to other legacy code and this being a database that is running on SQL 2000 I cannot make database alterations, but this code was working fine at one point and then simply stopped working. It is saying that :
Cannot insert the value NULL into column 'ID', table 'Order'; column does not allow nulls. INSERT fails.
But as you can see from the code and what I can CLEARLY see as I step through the code, the ID column is getting a valid ID number. For some reason even though I am setting the ID field it is attempting to insert it as a null even though this code was working fine before. I've gone so far as to completely restore the database and rebuilt the data layer, but to no avail.
I'm so stumped on this and out of time that I'm beside myself.
So, the answer to this is very strange and I'm not 100% certain of why. Essentially what I did was completely rebuild the LINQ to SQL data layer (merely dragging and dropping the same tables in the designer) and then completely cleaning and rebuilding the entire solution. After that the code magically worked again. No code change required.
For some reason the code was improperly cached and that caused it to not be able to transfer the object to the data layer (is my guess). It seems like a strange error to get back in that case.

Linq to SQL - Submit Changes not adding to database

I have this pretty simple method:
internal void Add(RecipeRecord recipeRecord)
{
this.Database.GetTable<RecipeRecord>().InsertOnSubmit(recipeRecord);
this.Database.SubmitChanges();
}
The entity I'm inserting is a valid entity. When I call SubmitChanges, nothing happens. No errors and no row added to the database. There is no transaction active. If I call GetChangeSet() on the context object, I see the single entity to add. After SubmitChanges(), the change set is empty.
Can anyone see what might be wrong?
I think you may have to use context.attach I ran in to a similar issue and that got me going in the right direction.

Entity-Framework -> MySql gives 'Function evaluation timed out.'

I having a weird problem with Entity Framework with MySql database.
Here's the code that I've got.
public class testbase
{
private testEntities db = new testEntities();
public IQueryable<post> GetRecords()
{
return db.record;
}
}
Here record is a table in my database and this could should return all the rows in the table. I have only one row in there and when I do a db.record.Count(), I get 1.
But when I try to retrieve the rows themselves I get 'Function Evaluation timed out'.
What's happening? Anybody got any ideas?
Okay, this turned out to be a dud question. Ben M was right. Some googling revealed: -
EF does not behave well while debugging due to some issues in VS debugger. You get a 'Function evaluation timed out'.
Things work swell when you try the code without debugging.
I was testing as I go for my new EF+MySql+ASP.Net.MVC app, and since I am a n00b at all three I didn't realize that.
I haven't deleted the question yet because there for others like me. It's on the community to decide whether to let this question survive or go.
I pronounce this question officially a dud.