Error from saveData()

Hello,

I want to write a record to the database.
But the saveData() return false, which means that the write was not succesfull.
I need to know what went wrong, why the record was not saved.
Probably some restriction or some relation setting, but I checked all and I didn’t find any problem.
How can I find what situation caused that my data was not written to the database.

I’m using 3.5 Final with SQL Server 2005

Thanks for your reply

Martin

No feedback in your log files or console?

No nothing at all.

There is a similar thread Errormessage from controller.deleteRecord - Classic Servoy - Servoy Community where Paul Bakker says that for a delete indeed no errormessage occurs. But now I have a add situation.

Perhaps the same problem, perhaps not; I don’t know.

What is the usual way to check if the saveData() was in an error state?

To be quite honest, I have never had an issue like this but it seems very strange to me that you see no feedback.

also what could happen is that the UI is blocking it.
If you have an onchange on a field that return false. Then saveData() will return false.

Also where do you call saveData() do you do that for example in an onChange method of a field?
That should be not a problem in 3.5 anymore but just to check.

Also if you have table events like onUpdate or onInsert those could also block your save.

I don’t have any onUpdate, onInsert or onDelete events.
I have a general framework that handles all database transactions. I show you a part of the framework:

The forms[_form] is my currentform

databaseManager.startTransaction()


if(forms[_form].onPreSave)
{
	_methodReturn = forms[_form].onPreSave()
	
	if(_methodReturn == -1)
	{
		_errormessage = ServoyException.getMessage();
		databaseManager.rollbackEditedRecords();
		databaseManager.rollbackTransaction()	;			
		if 	(_errormessage == '')
			plugins.dialogs.showErrorDialog('Save record', 'Due to database restictions the record could not be saved','OK');
		else
			plugins.dialogs.showErrorDialog('Save record', _errormessage,'OK');		
		return;
	}
}


_success = forms[_form].controller.saveData();
if (_success == false)
{
	_errormessage = ServoyException.getMessage();
	
	databaseManager.rollbackEditedRecords();
	databaseManager.rollbackTransaction();	
	if 	(_errormessage == '')
		plugins.dialogs.showErrorDialog('Save record', 'Due to database restictions the record could not be saved','OK');
	else
		plugins.dialogs.showErrorDialog('Save record', _errormessage,'OK');		
	return;		
}



databaseManager.commitTransaction()

The onPreSave method looks as follows, but I don’t have the idea that it has something to do with it:

var _query
var _exception
var _success

sequence_nr = salesorderline_to_salesorder.sequence_nr_line + 5

_query = 'UPDATE salesorder \
			SET sequence_nr_line = ' + sequence_nr + ' \
			WHERE salesorder_id = ' + salesorder_id

_success = plugins.rawSQL.executeSQL( globals.sec_db_connection,  'salesorder',  _query)

if (_success == false)
{
	var msg = plugins.rawSQL.getException().getMessage(); //see exception node for more info about the exception obj
	plugins.dialogs.showErrorDialog('Error',  'SQL exception: '+msg,  'Ok')
	return -1;
}

return;

This line is returning false:
_success = forms[_form].controller.saveData();

I think that there is some restriction somewhere, which causes that the data can not be written. Think about Null-values not allowed or an invalid relation. The problem is, that I don’t get any errormessage, so I really don’t know what is wrong.

I even tried to give the variable ‘_success’ the value true and continue the transaction, but the data was not written to the database.

I also noticed that sometimes, it does work after several times trying to add a record, with the same data. That makes it even stranger. Therefore if I can get the errormessage, why the saveData() didn’t succeed, perhaps I can find out where the problem is. Can be in my application also, but without errormessage, it is difficult to find. Specially when occasionally the record was added.

So if there is a way that I can determine the errormessage, it would help me a lot already.

So, these are global methods?

What when you perform the same on the actual/current form without forms prefixes etc.?

I tried this, but I don’t see any changes.
But I do see something else.
I have on a field a OnFocusLost event

In this event some other fields are filled:

if (salesorderline_to_article$article_code)
{
	article_id = salesorderline_to_article$article_code.article_id
	vat_id = salesorderline_to_article.article_to_articletype.vat_id	
	
	_price_array = globals.getArticlePrice(salesorderline_to_salesorder.relation_id, article_id, controller.getName(), quantity);
	if (_price_array)
	{
		price=_price_array[0];	
		price_per = _price_array[1];
		ordered_articleunit_id=_price_array[2];
		elements.quantity.requestFocus(true)
	}
}

And it looks like here is something going wrong. The field vat_id is not filled often and that causes probably the error, because vat_id has null value not allowed.
When I use the debugger to step all lines, all goes well. But as soon as I run without the debugger, it doesn’t work. Looks like some synchronisation problem:

article_id = salesorderline_to_article$article_code.article_id

This relation is based on article_code and determines the article_id.
This goes always correct. With or without debugger. I’ve put the article_id on the screen and I see correct value.

But it goes wrong on the second line:

vat_id = salesorderline_to_article.article_to_articletype.vat_id

The salesorderline_to_article relation is based on article_id which was just be determined in the previous line. It looks like Servoy doesn’t have the time to bring this relation in a correct state and therefor vat_id doesn’t have a correct value. Does this make any sense? And is there a way to avoid this case. Should I make some reload on the relation?

Just a remark: if you use a transaction there is no need to call rollbackEditedRecords() (that refers to Servoy’s “internal transactions”).

Yes, this does make sense.

I am not sure but can you try to force a saveData() before you perform that second line code (which goes wrong)?

That is not possible. I would not be written to the database, because vat_id has a null value.
And also databaseManager.setAutoSave(false) was set

I tried to save between those lines, but it doesn’t work

Hmm, tricky… Don’t have an answer right now. I’m sorry…

What if you test for that relation:

if (utils.hasRecords(salesorderline_to_article.article_to_articletype)) {
   vat_id = salesorderline_to_article.article_to_articletype.vat_id
}
else {
   application.output('Could not find vat_id');
}

Also: did you have a look at the server log to see if you get an error there?

first change this:

I tried this, but I don’t see any changes.
But I do see something else.
I have on a field a OnFocusLost event

don’t do it on an onFocusLost event. do it on a onDataChange event.
focus lost should only be used for ui changes like setting colors on fields.

When is that saveMethod triggered?
is that triggered by a button? when you leave the field that has the onFocusEvent? That can cause weird things like you describe of not saving stuff because not all is saved! (and that it works in the debugger because the events are slightly different because of focus events)

On a different note:

The onPreSave method looks as follows, but I don’t have the idea that it has something to do with it:

Code: 

var _query
var _exception
var _success

sequence_nr = salesorderline_to_salesorder.sequence_nr_line + 5

_query = 'UPDATE salesorder \
SET sequence_nr_line = ’ + sequence_nr + ’ \
WHERE salesorder_id = ’ + salesorder_id

_success = plugins.rawSQL.executeSQL( globals.sec_db_connection, ‘salesorder’, _query)

if (_success == false)
{
var msg = plugins.rawSQL.getException().getMessage(); //see exception node for more info about the exception obj
plugins.dialogs.showErrorDialog(‘Error’, 'SQL exception: '+msg, ‘Ok’)
return -1;
}

return;

Why are you using the rawSQL plugin? It’s not needed in this situation, it invalidated the datacache of Servoy (and you do not flush it to bring it back in sync).

The rawSQL plugin is a last resort, only to be used for things that are not possible in Servoy imho. For example: datamodel changes.

A simple update of a value in a record can be easily done through the normal Servoy function.

Paul