Регистрация  |  Вход

Цепочка зависимости от Parent записи к Child из-за SumUp формульных полей

Здравствуйте!

Столкнулся с интересной бизнес-логико-организационной ситуацией в приложении.

Есть цепочка записей Дедушка-Родитель-Дети.

Делаю ВФ страницу, которая создает родителя и дочерние записи. Так вот, кто-то добавил на Дедушку новое ВалРул, и часть Дедушкиных записей оказалось в "нередактируемом" положении, то есть существующая комбинация значений в полях провоцирует новое ВалРул при попытке апдатировать запись по какому-либо поводу.

Ну и ладно, как это касается моей возни с новой ВФ страницей? а вот как: я не могу вставить Родителя (или даже дочернюю запись, если б такое требовалось), т.к. все эти три уровня записей связаны SumUp полям, то есть при попытки вставить Родителя, у Дедушки происходит апдатирования на SumUp поле, а Дедушку то нельзя "кантовать" из-за нового ВалРула.

(PS все даже немного сложнее, чем я описал выше: я не могу вставить Дочернуюю запись из-за проблем на Дедушки, а связаны они цепочкой формульных полей, что в общем то обычная структура для приложения)

Получается на своей ВФ странице я вывожу пользователю Ошубку, которая вообще не относится к тому что он делает и должен знать, эта ошибка - это сообщение ВалРула от дедушкиной записи...

вот сижу и думаю, как все это правильно организовать? Этим, ведь, людям (Биз аналитикам) можно сказать чтоб острожнее создавали ВалРулы, но ведь на это нельзя надеяться...


И к слову, как вы отрабатываете ситуацию последовательной вставки Родителя и Дочерней записи, т.е. проблемы могут возникнуть если вставка Дочерней записи "обломилась", а родительская запись то вставилась, а она не имеет смысла без дочерних...

так пойдет?

Savepoint sp = Database.setSavepoint();
try{
insert parent;

child.MyParent__c = parent.id;

insert child;
}
catch(exception ex){
Database.rollback(sp);
}

Здравствуйте!

Столкнулся с интересной бизнес-логико-организационной ситуацией в приложении.

Есть цепочка записей Дедушка-Родитель-Дети.

Делаю ВФ страницу, которая создает родителя и дочерние записи. Так вот, кто-то добавил на Дедушку новое ВалРул, и часть Дедушкиных записей оказалось в "нередактируемом" положении, то есть существующая комбинация значений в полях провоцирует новое ВалРул при попытке апдатировать запись по какому-либо поводу. 

Ну и ладно, как это касается моей возни с новой ВФ страницей? а вот как: я не могу вставить Родителя  (или даже дочернюю запись, если б такое требовалось), т.к. все эти три уровня записей связаны SumUp полям, то есть при попытки вставить Родителя, у Дедушки происходит апдатирования на SumUp поле, а Дедушку то нельзя "кантовать" из-за нового ВалРула.

[i](PS все даже немного сложнее, чем я описал выше: я не могу вставить Дочернуюю запись из-за проблем на Дедушки, а связаны они цепочкой формульных полей, что в общем то обычная структура для приложения)[/i]

Получается на своей ВФ странице я вывожу пользователю Ошубку, которая вообще не относится к тому что он делает и должен знать, эта ошибка - это сообщение ВалРула от дедушкиной записи...

вот сижу и думаю, как все это правильно организовать? Этим, ведь, людям (Биз аналитикам) можно сказать чтоб острожнее создавали ВалРулы, но ведь на это нельзя надеяться...


И к слову, как вы отрабатываете ситуацию последовательной вставки Родителя и Дочерней записи, т.е. проблемы могут возникнуть если вставка Дочерней записи "обломилась", а родительская запись то вставилась, а она не имеет смысла без дочерних...

так пойдет?

[code]Savepoint sp = Database.setSavepoint();
try{
    insert parent;

    child.MyParent__c = parent.id;

    insert child;
}
catch(exception ex){
    Database.rollback(sp);
}[/code]




Отличную тему поднял. Сам когда начинал с SF столкнулся с такой проблемой что при наличии Rollup Summary родитель тоже обновляется при обновлении подчиненного. И если родитель не может обновиться то валится обновление у подчиненного.

Я тогда был еще неопытен, поэтому реально ломал голову полдня и даже хотел отписать старшим лидам что SF неисправен. А вот как оно вышло в итоге.

Честно так и не нашел подходящего варианта как это обойти. Но в моем случае это и не нужно было - родители просто должны были быть валидными.

Делать Savepoint для Salesforce необязательно (да честно и не встречалось мне таких ситуаций где он нужен был). При exception вся транзакция за этот вызов откатывается. Поэтому даже если отвалится последняя DML в цепочке откатятся все предыдущие.

Не уверен, но попробуй Database.insert(..., false). Может то что отваливается родитель не повлияет на вставку подчиненного. !Но это предположение.

Отличную тему поднял. Сам когда начинал с SF столкнулся с такой проблемой что при наличии Rollup Summary родитель тоже обновляется при обновлении подчиненного. И если родитель не может обновиться то валится обновление у подчиненного. 

Я тогда был еще неопытен, поэтому реально ломал голову полдня и даже хотел отписать старшим лидам что SF неисправен. А вот как оно вышло в итоге. 

Честно так и не нашел подходящего варианта как это обойти. Но в моем случае это и не нужно было - родители просто должны были быть валидными.

Делать Savepoint для Salesforce необязательно (да честно и не встречалось мне таких ситуаций где он нужен был). При exception вся транзакция за этот вызов откатывается. Поэтому даже если отвалится последняя DML в цепочке откатятся все предыдущие.

Не уверен, но попробуй Database.insert(..., false). Может то что отваливается родитель не повлияет на вставку подчиненного. !Но это предположение.

Dmitry Shnyrev
родители просто должны были быть валидными

к родителям-записям нет вопросов, есть вопрос к нам людям:

(1) как организационно избежать таких ловушек? объяснять Биз аналитикам проблему? я кстати видел подобную ситуацию спровоцированную пользователем: они поменяли РекТайп на одной записи, после чего где-то связь между записями перестала быть валидной (из-за фильтра на Лук-Апе) и все "дерево" дочерних записей "зависло"...

(2) как избежать показа пользователям эррор сообщений, по части их не касающихся? Например, показывать только те ДМЛ сообщения, которые относятся непосредственно к вставляемым пользователем записям, а не свалившиеся откуда-то сверху (эти сообщения перекрывать специальным кастомным сообщением)?

Dmitry Shnyrev
При exception вся транзакция за этот вызов откатывается.

как это откатывается? ведь уже исполнившийся код в try{} не откатывается назад при уходе в catch?

[quote="Dmitry Shnyrev"]родители просто должны были быть валидными[/quote]

к родителям-записям нет вопросов, есть вопрос к нам людям:

(1) как организационно избежать таких ловушек? объяснять Биз аналитикам проблему? я кстати видел подобную ситуацию спровоцированную пользователем: они поменяли РекТайп на одной записи, после чего где-то связь между записями перестала быть валидной (из-за фильтра на Лук-Апе) и все "дерево" дочерних записей "зависло"...

(2) как избежать показа пользователям эррор сообщений, по части их не касающихся? Например, показывать только те ДМЛ сообщения, которые относятся непосредственно к вставляемым пользователем записям, а не свалившиеся откуда-то сверху (эти сообщения перекрывать специальным кастомным сообщением)?



 [quote="Dmitry Shnyrev"]При exception вся транзакция за этот вызов откатывается.[/quote]

как это откатывается? ведь уже исполнившийся код в try{} не откатывается назад при уходе в catch?

Den Brown
как это откатывается? ведь уже исполнившийся код в try{} не откатывается назад при уходе в catch?

ДО try не откатывается, а внутри try откатывается. Если я ничего не путаю. Проверь, расскажешь

Den Brown
(2) как избежать показа пользователям эррор сообщений, по части их не касающихся?

Да, отлавливать DMLexception и показывать кастомное сообщение.
Да и вообще пользователям всегда показывать только кастомные сообщения и только те, которые их касаются. При любой исключительной ситуации выводить общее сообщение "Server error. Please contact administrator", а саму ошибку писать в логи чтобы потом разобраться.

[quote="Den Brown"]как это откатывается? ведь уже исполнившийся код в try{} не откатывается назад при уходе в catch?[/quote]
ДО try не откатывается, а внутри try откатывается. Если я ничего не путаю. Проверь, расскажешь :) 

[quote="Den Brown"](2) как избежать показа пользователям эррор сообщений, по части их не касающихся?[/quote]
Да, отлавливать DMLexception и показывать кастомное сообщение.
Да и вообще пользователям всегда показывать только кастомные сообщения и только те, которые их касаются. При любой исключительной ситуации выводить общее сообщение "Server error. Please contact administrator", а саму ошибку писать в логи чтобы потом разобраться.

Den Brown
как организационно избежать таких ловушек? объяснять Биз аналитикам проблему?

Побольше "защит от дурака" чтобы не возникало таких ловушек. Иначе если не смог предусмотреть выводить сообщения как я написал выше, чтобы пользователь не ломал голову.

Жаль у SF разработчиков не хватает знаний из других областей web dev.
Например в любой языке учат что ошибки выкидывать надо только при debug=true, а в остальных случаях Internal Error. А в SF мы привыкли что каждый пользователь минимум администратор и выкидываем ошибки еще со stack trace прямо на страницу.

Как и с транзакциями тоже расслабились - не знаем что и когда откатывается. На других платформах если SQL запрос произошел, то он уже произошел и ничего не вернуть, поэтому разработчики сами заботятся о транзакциях и целостности данных. А в SF все на блюдичке - получил exception, данные откатились и никто не думает какие данные и насколько далеко откатились.

[quote="Den Brown"]как организационно избежать таких ловушек? объяснять Биз аналитикам проблему?[/quote]
Побольше "защит от дурака" чтобы не возникало таких ловушек. Иначе если не смог предусмотреть выводить сообщения как я написал выше, чтобы пользователь не ломал голову.

Жаль у SF разработчиков не хватает знаний из других областей web dev. 
Например в любой языке учат что ошибки выкидывать надо только при debug=true, а в остальных случаях Internal Error. А в SF мы привыкли что каждый пользователь минимум администратор и выкидываем ошибки еще со stack trace прямо на страницу.

Как и с транзакциями тоже расслабились - не знаем что и когда откатывается. На других платформах если SQL запрос произошел, то он уже произошел и ничего не вернуть, поэтому разработчики сами заботятся о транзакциях и целостности данных. А в SF все на блюдичке - получил exception, данные откатились и никто не думает какие данные и насколько далеко откатились.

Dmitry Shnyrev
Да, отлавливать DMLexception и показывать кастомное сообщение.

на объекте вставляемой записи могут быть собственные Вал рулсы. Как я понимаю, их сообщения, необходимые пользователю, вернутся в DMLexception. Поэтому ставить сообщение-"загрушку" для всех Еxception не получится...

[quote="Dmitry Shnyrev"]Да, отлавливать DMLexception и показывать кастомное сообщение. [/quote]

на объекте вставляемой записи могут быть собственные Вал рулсы. Как я понимаю, их сообщения, необходимые пользователю, вернутся в DMLexception. Поэтому ставить сообщение-"загрушку" для всех Еxception не получится...

Dmitry Shnyrev
ДО try не откатывается, а внутри try откатывается. Если я ничего не путаю. Проверь, расскажешь

Проверил в "Execute Anonymous", рассказываю:

если

insert parent;

child.MyParent__c = parent.id;

insert child;

взяты в Трай, то несмотря на DMLException по собственному Вал рулу у child, parent еще как вставляется...
(и Savepoint решает проблему)

а вот если insert-ы делаются без Трая, "голиком", то код выпадает в исключение и ничего не сохраняется.

кстати, что если ошибка пришла с родительской запси по Вал рулу или с собственого Вал рула, то все одно это будет один тип исключения DMLException, и так просто сообщения не разрулить: что показывать пользователю, что нет. Придется читать мэсаджи и пропускать только годные, но это как то нехорошо, так подразумевает хардкод...

[quote="Dmitry Shnyrev"]ДО try не откатывается, а внутри try откатывается. Если я ничего не путаю. Проверь, расскажешь[/quote]

Проверил в "Execute Anonymous", рассказываю:

если 
[code]    insert parent;
 
    child.MyParent__c = parent.id;
 
    insert child;[/code]

взяты в Трай, то несмотря на DMLException по собственному Вал рулу у child, parent еще как вставляется...
[i](и Savepoint решает проблему)[/i]

а вот если  insert-ы делаются без Трая, "голиком", то код выпадает в исключение и ничего не сохраняется.

кстати, что если ошибка пришла с родительской запси по Вал рулу или с собственого Вал рула, то все одно это будет один тип исключения DMLException, и так просто сообщения не разрулить: что показывать пользователю, что нет. Придется читать мэсаджи и пропускать только годные, но это как то нехорошо, так подразумевает хардкод...

Den Brown
взяты в Трай, то несмотря на DMLException по собственному Вал рулу у child, parent еще как вставляется...
(и Savepoint решает проблему)

Хм. Очень интересно. Я думал что работает как раз наоборот.

[quote="Den Brown"]взяты в Трай, то несмотря на DMLException по собственному Вал рулу у child, parent еще как вставляется... 
(и Savepoint решает проблему)[/quote]
Хм. Очень интересно. Я думал что работает как раз наоборот.