Shallow update and non-nullable fields [message #954096] |
Mon, 22 October 2012 15:44  |
Eclipse User |
|
|
|
We have the following tables:
TRANSACTION 1:n TRANSACTION_EVENT
and TRANSACTION has reference to last transaction event.
TRANSACTION_EVENT mapped to TRANSACTION as private-owned.
When deleting transaction the following sequence applied:
In toplink 9.0.3
DELETE FROM TRANSACTION_EVENT WHERE TRANSACTION_EVENT_ID = 1;
DELETE FROM TRANSACTION_EVENT WHERE TRANSACTION_EVENT_ID = 2;
--The event below is referenced from TRANSACTION like last transaction event, but there is no error
DELETE FROM TRANSACTION_EVENT WHERE TRANSACTION_EVENT_ID = 3;
DELETE FROM TRANSACTION WHERE TRANSACTION_ID = 1;
Now eclipselink makes shallow update for TRANSACTION before deleting last event. And it's fail because TRANSACTION has some non-nullable foreign keys.
DELETE FROM TRANSACTION_EVENT WHERE TRANSACTION_EVENT_ID = 1;
DELETE FROM TRANSACTION_EVENT WHERE TRANSACTION_EVENT_ID = 2;
--Shallow update: All foreign keys set to NULL. SQL error appears here since there is some non-nullable foreign keys
UPDATE TRANSACTION SET LAST_TRANSACTION_EVENT_ID = NULL, CURRENCY_ID = NULL WHERE TRANSACTION_ID = 1;
DELETE FROM TRANSACTION_EVENT WHERE TRANSACTION_EVENT_ID = 3;
DELETE FROM TRANSACTION WHERE TRANSACTION_ID = 1;
It seems that class OneToOneMapping has some code that should solve this problem, but it not works because flag nullable is not setted in DatabaseField (it's always true)
protected void writeFromObjectIntoRowInternal(Object object, AbstractRecord databaseRow, AbstractSession session, ShallowMode mode) {
List<DatabaseField> foreignKeyFields = getForeignKeyFields();
if (mode != null) {
List<DatabaseField> nonNullableFields = null;
for (DatabaseField field : foreignKeyFields) {
if (field.isNullable()) {
if (mode == ShallowMode.Insert) {
// add a nullable field with a null value
databaseRow.add(field, null);
}
} else {
if (nonNullableFields == null) {
nonNullableFields = new ArrayList<DatabaseField>();
}
nonNullableFields.add(field);
}
}
I have applied workaround to skip shallow update before delete and it works for this case.
So my questions are:
1) Is there some common practice how to set flag nullable in DatabaseField? Maybe it can be setted from deployment descriptor generated by workbench?
2) How did it even work without shallow update? To see maybe I can rely on my workaround.
|
|
|
|
|
|
Powered by
FUDForum. Page generated in 0.05668 seconds