Can Cast Child Related List to Single SObject Record - Compiler error?
Clash Royale CLAN TAG#URR8PPP
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;
up vote
13
down vote
favorite
This situation came up in code review and I was sure the old version should have caused a compile fail:
List<Child__c> children = new List<Child__c>();
for (Parent__c parent : parents)
children.add(parent.Children__r); // old version
children.addAll(parent.Children__r); // new version
Obviously, this code blew up as soon as it was run against a parent having multiple children (or none). Now, I understand why it is allowed, since you can assign a query result to a single record or to a collection. It just seems like this behavior should not be allowed for a related list. My question is, should this code have failed to compile? Is it a compiler bug, odd quirk of the language, or something else entirely?
apex soql query childrelationship
add a comment |Â
up vote
13
down vote
favorite
This situation came up in code review and I was sure the old version should have caused a compile fail:
List<Child__c> children = new List<Child__c>();
for (Parent__c parent : parents)
children.add(parent.Children__r); // old version
children.addAll(parent.Children__r); // new version
Obviously, this code blew up as soon as it was run against a parent having multiple children (or none). Now, I understand why it is allowed, since you can assign a query result to a single record or to a collection. It just seems like this behavior should not be allowed for a related list. My question is, should this code have failed to compile? Is it a compiler bug, odd quirk of the language, or something else entirely?
apex soql query childrelationship
1
I don't think it would have failed to compile. It's definitely more of a runtime exception E.g.,Account a = [select Name from Account]
will compile but will throw a runtime exception if there are more than 1 or no record. So something similar to this construct, adding it to the list would still compile but fail only in the scenario you have mentioned.
â Jayant Das
Aug 22 at 15:35
add a comment |Â
up vote
13
down vote
favorite
up vote
13
down vote
favorite
This situation came up in code review and I was sure the old version should have caused a compile fail:
List<Child__c> children = new List<Child__c>();
for (Parent__c parent : parents)
children.add(parent.Children__r); // old version
children.addAll(parent.Children__r); // new version
Obviously, this code blew up as soon as it was run against a parent having multiple children (or none). Now, I understand why it is allowed, since you can assign a query result to a single record or to a collection. It just seems like this behavior should not be allowed for a related list. My question is, should this code have failed to compile? Is it a compiler bug, odd quirk of the language, or something else entirely?
apex soql query childrelationship
This situation came up in code review and I was sure the old version should have caused a compile fail:
List<Child__c> children = new List<Child__c>();
for (Parent__c parent : parents)
children.add(parent.Children__r); // old version
children.addAll(parent.Children__r); // new version
Obviously, this code blew up as soon as it was run against a parent having multiple children (or none). Now, I understand why it is allowed, since you can assign a query result to a single record or to a collection. It just seems like this behavior should not be allowed for a related list. My question is, should this code have failed to compile? Is it a compiler bug, odd quirk of the language, or something else entirely?
apex soql query childrelationship
asked Aug 22 at 15:25
Adrian Larsonâ¦
100k19105223
100k19105223
1
I don't think it would have failed to compile. It's definitely more of a runtime exception E.g.,Account a = [select Name from Account]
will compile but will throw a runtime exception if there are more than 1 or no record. So something similar to this construct, adding it to the list would still compile but fail only in the scenario you have mentioned.
â Jayant Das
Aug 22 at 15:35
add a comment |Â
1
I don't think it would have failed to compile. It's definitely more of a runtime exception E.g.,Account a = [select Name from Account]
will compile but will throw a runtime exception if there are more than 1 or no record. So something similar to this construct, adding it to the list would still compile but fail only in the scenario you have mentioned.
â Jayant Das
Aug 22 at 15:35
1
1
I don't think it would have failed to compile. It's definitely more of a runtime exception E.g.,
Account a = [select Name from Account]
will compile but will throw a runtime exception if there are more than 1 or no record. So something similar to this construct, adding it to the list would still compile but fail only in the scenario you have mentioned.â Jayant Das
Aug 22 at 15:35
I don't think it would have failed to compile. It's definitely more of a runtime exception E.g.,
Account a = [select Name from Account]
will compile but will throw a runtime exception if there are more than 1 or no record. So something similar to this construct, adding it to the list would still compile but fail only in the scenario you have mentioned.â Jayant Das
Aug 22 at 15:35
add a comment |Â
1 Answer
1
active
oldest
votes
up vote
12
down vote
accepted
Yes, it's always legal to assign a List<SObject>
that came from a query into a SObject
variable, and it will succeed during runtime only if there's exactly one element. Note that child objects are always considered to have come from a query, so the following code compiles (but obviously crashes):
Account a = new Account();
Contact c = a.Contacts;
However, this is not true for native lists:
// Does not compile //
Account a = new Account[1];
Any time the compiler thinks that a particular list may have come from a query, it will allow this automatic assignment.
Obviously, since the risk for runtime errors exists, you should only use this code syntax if you are absolutely certain only one row will be returned.
This is a convenience syntax that has been around since the beginning of Apex. I'm not even sure if it's in the documentation, and honestly, it's more trouble than its worth most of the time; if it had been up to me, I would not allowed this syntax to exist, since it is so easy to create code that looks fine but crashes "randomly."
add a comment |Â
1 Answer
1
active
oldest
votes
1 Answer
1
active
oldest
votes
active
oldest
votes
active
oldest
votes
up vote
12
down vote
accepted
Yes, it's always legal to assign a List<SObject>
that came from a query into a SObject
variable, and it will succeed during runtime only if there's exactly one element. Note that child objects are always considered to have come from a query, so the following code compiles (but obviously crashes):
Account a = new Account();
Contact c = a.Contacts;
However, this is not true for native lists:
// Does not compile //
Account a = new Account[1];
Any time the compiler thinks that a particular list may have come from a query, it will allow this automatic assignment.
Obviously, since the risk for runtime errors exists, you should only use this code syntax if you are absolutely certain only one row will be returned.
This is a convenience syntax that has been around since the beginning of Apex. I'm not even sure if it's in the documentation, and honestly, it's more trouble than its worth most of the time; if it had been up to me, I would not allowed this syntax to exist, since it is so easy to create code that looks fine but crashes "randomly."
add a comment |Â
up vote
12
down vote
accepted
Yes, it's always legal to assign a List<SObject>
that came from a query into a SObject
variable, and it will succeed during runtime only if there's exactly one element. Note that child objects are always considered to have come from a query, so the following code compiles (but obviously crashes):
Account a = new Account();
Contact c = a.Contacts;
However, this is not true for native lists:
// Does not compile //
Account a = new Account[1];
Any time the compiler thinks that a particular list may have come from a query, it will allow this automatic assignment.
Obviously, since the risk for runtime errors exists, you should only use this code syntax if you are absolutely certain only one row will be returned.
This is a convenience syntax that has been around since the beginning of Apex. I'm not even sure if it's in the documentation, and honestly, it's more trouble than its worth most of the time; if it had been up to me, I would not allowed this syntax to exist, since it is so easy to create code that looks fine but crashes "randomly."
add a comment |Â
up vote
12
down vote
accepted
up vote
12
down vote
accepted
Yes, it's always legal to assign a List<SObject>
that came from a query into a SObject
variable, and it will succeed during runtime only if there's exactly one element. Note that child objects are always considered to have come from a query, so the following code compiles (but obviously crashes):
Account a = new Account();
Contact c = a.Contacts;
However, this is not true for native lists:
// Does not compile //
Account a = new Account[1];
Any time the compiler thinks that a particular list may have come from a query, it will allow this automatic assignment.
Obviously, since the risk for runtime errors exists, you should only use this code syntax if you are absolutely certain only one row will be returned.
This is a convenience syntax that has been around since the beginning of Apex. I'm not even sure if it's in the documentation, and honestly, it's more trouble than its worth most of the time; if it had been up to me, I would not allowed this syntax to exist, since it is so easy to create code that looks fine but crashes "randomly."
Yes, it's always legal to assign a List<SObject>
that came from a query into a SObject
variable, and it will succeed during runtime only if there's exactly one element. Note that child objects are always considered to have come from a query, so the following code compiles (but obviously crashes):
Account a = new Account();
Contact c = a.Contacts;
However, this is not true for native lists:
// Does not compile //
Account a = new Account[1];
Any time the compiler thinks that a particular list may have come from a query, it will allow this automatic assignment.
Obviously, since the risk for runtime errors exists, you should only use this code syntax if you are absolutely certain only one row will be returned.
This is a convenience syntax that has been around since the beginning of Apex. I'm not even sure if it's in the documentation, and honestly, it's more trouble than its worth most of the time; if it had been up to me, I would not allowed this syntax to exist, since it is so easy to create code that looks fine but crashes "randomly."
answered Aug 22 at 15:44
sfdcfox
225k10171384
225k10171384
add a comment |Â
add a comment |Â
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
StackExchange.ready(
function ()
StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fsalesforce.stackexchange.com%2fquestions%2f229763%2fcan-cast-child-related-list-to-single-sobject-record-compiler-error%23new-answer', 'question_page');
);
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
1
I don't think it would have failed to compile. It's definitely more of a runtime exception E.g.,
Account a = [select Name from Account]
will compile but will throw a runtime exception if there are more than 1 or no record. So something similar to this construct, adding it to the list would still compile but fail only in the scenario you have mentioned.â Jayant Das
Aug 22 at 15:35