apex-enterprise-patterns / fflib-apex-common

Common Apex Library supporting Apex Enterprise Patterns and much more!
BSD 3-Clause "New" or "Revised" License
913 stars 517 forks source link

Invalid Field 'CreatedDate' for object 'ContentDocumentLink' #214

Closed slimble closed 1 year ago

slimble commented 5 years ago

Hi there,

I am trying to query the ContentDocumentLink Object. When I write my query directly into my Service class as List<ContentDocumentLink> cdlList = [SELECT ContentDocumentId, LinkedEntityId FROM ContentDocumentLink WHERE ContentDocumentId IN :contentDocIdSet]; it works fine however if I use this code in my service class

Set<Id> contentDocIdSet = new Set<Id>(); for(ContentDocument con : contentDocumentList) { contentDocIdSet.add(con.Id); }

    `SRV_ContentDocumentLinkSelector cdlSelector = new SRV_ContentDocumentLinkSelector();
    List<ContentDocumentLink> cdlList = cdlSelector.selectByContentDocumentId(contentDocIdSet); `

And the following in my selector class

`public with sharing class SRV_ContentDocumentLinkSelector extends fflib_SObjectSelector { public Schema.SObjectType getSObjectType() { return ContentDocumentLink.SObjectType; }

public List<Schema.SObjectField> getSObjectFieldList() {
    return new List<Schema.SObjectField> {
            ContentDocumentLink.ContentDocumentId,
            ContentDocumentLink.LinkedEntityId,
            ContentDocumentLink.ShareType,
            ContentDocumentLink.Visibility

    };
}

public List<ContentDocumentLink> selectByContentDocumentId(Set<Id> cdSet) {
    return Database.query(
            newQueryFactory(false, false, true)
                    .setCondition('ContentDocumentId IN :cdSet')
                    .toSOQL());
}

}`

I receive an error "Invalid Field 'CreatedDate' for object 'ContentDocumentLink' however this object does not contain a CreatedDate field

cropredyHelix commented 5 years ago

The reason this happens is you did not provide a getOrderBy() for your selector. If you omit this, the queryfactory defaults to CreatedDate using this code

public virtual String getOrderBy()
    {
        if(m_orderBy == null) {
        m_orderBy = 'CreatedDate';
        if(describeWrapper.getNameField() != null) {
                m_orderBy = describeWrapper.getNameField().getDescribe().getName();
            }
    }
    return m_orderBy;
    }

Personally, I tend to use a getOrderBy() that returns an autonumber field by default, if one exists for the sobject as that makes writing tests easier

daveespo commented 1 year ago

As @cropredyHelix said, the simple solution here is to define a getOrderBy rather than rely on the default implementation