The field HasOpportunityLineItem
is a standard field, not visible in the UI which is automatically calculated by Salesforce. As the documentation states:
Read-only field that indicates whether the opportunity has associated
line items. A value of true means that Opportunity line items have
been created for the opportunity. An opportunity can have opportunity
line items only if the opportunity has a price book. The opportunity
line items must correspond to PricebookEntry objects that are listed
in the opportunity Pricebook2. However, you can insert opportunity
line items on an opportunity that does not have an associated
Pricebook2. For the first opportunity line item that you insert on an
opportunity without a Pricebook2, the API automatically sets the
Pricebook2Id field, if the opportunity line item corresponds to a
PricebookEntry in an active Pricebook2 that has a CurrencyIsoCode
field that matches the CurrencyIsoCode field of the opportunity. If
the Pricebook2 is not active or the CurrencyIsoCode fields do not
match, then the API returns an error. You can’t update the
Pricebook2Id or PricebookId fields if opportunity line items exist on
the Opportunity. You must delete the line items before attempting to
update the PricebookId field.
Therefore, you cannot set it yourself.
Furthermore, take into account that when you insert an opportunity and an opportunity line item, in order to have the actual value of HasOpportunityLineItem
you need to query again the opportunity. This is because the value gets updated in the server, while your object instance in Apex does not update after an insert.
Run this code in a test or anonymous apex to try:
Account acc = new Account(/* Required acc fields */);
insert acc;
Opportunity opp = new Opportunity(/* Required opp fields*/);
insert opp;
OpportunityLineItem oli = new OpportunityLineItem(/* Required line item fields */);
insert oli;
System.assert(true, [SELECT HasOpportunityLineItem FROM Opportunity WHERE Id =: opp.Id].HasOpportunityLineItem );