9

I have a custom object called Visitor with two custom fields, Name and Identifier. I am trying to add a record with this piece of controller code:

 public String getResponse() {
        System.debug('I am in!');

        if(validate()) {
            Visitor newVisitor = new Visitor();
            newVisitor.Name = 'John Smith';
            newVisitor.Identifier = 'john@somewhere.com';
            insert newVisitor;
            return '{"success":"true"}';
        }

        return '{"success":"false"}';
    }

When I try to save my code, I get this error:

Compile Error: Invalid type: Visitor at line 13 column 38

What am I doing wrong here?

  • 1
    people here are always gentle and very helpful. :) If you are satisfied with the answer given pls accept it. Welcome to APEX.. – Prady Nov 23 '12 at 2:01
18

Visitor should be Visitor__c. All custom objects are suffixed with __c, as should all of your custom fields on either standard or custom objects. So, your code would look something like this:

Visitor__c newVisitor = new Visitor__c ();
newVisitor.Name = 'John Smith';
newVisitor.Identifier__c = 'john@somewhere.com';
insert newVisitor;

Only standard fields are not suffixed with __c, e.g. Name, Id, CreatedDate etc.

EDIT: boots and braces with Try/Catch

See the docs for a full description of the Insert operation:

http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_dml_insert.htm

Doing a DML insert/update/upsert could result in an exception depending on a number of factors:

  • It could be that the operation will mean that you exceed a Governor limit (see
    http://www.salesforce.com/us/developer/docs/apexcode/Content/apex_gov_limits.htm). If you are inserting multiple records, 'bulkification' will most likely be required to prevent this.
  • It could also (and more likely) be caused by an issue with the record that you are trying to insert (e.g. missing required field, failed validation etc.).

Surrounding your operation with a Try/Catch is always good practice and will allow you to fail gracefully should the worst happen. Note, you cannot fail gracefully with a Try/Catch for a Governor limit issue.

There are essentially two ways to Try/Catch for DML statements (sorry, formatting has gone screwy):

This will suffice for a single record (though you could use the second option here too):

try
{
    insert newVisitor;
}
catch( DmlException ex )
{
    // fail gracefully
}

This may be preferable for multiple records, where the 'false' parameter indicates that this is (not) an 'all or nothing' insert:

Database.SaveResult[] MySaveResult = Database.Insert(newVisitors, false);
for (Database.SaveResult sr : MySaveResult) {
    if (!sr.isSuccess()) {
        // Operation failed, so get all errors                
        for(Database.Error err : sr.getErrors()) {
            System.debug('The following error has occurred.');                    
            System.debug(err.getStatusCode() + ': ' + err.getMessage());
            System.debug('Fields that affected this error: ' + err.getFields());
        }
    }
}
  • Identifier__c too ;) Phil, maybe you can simply post fixed code snippet? – eyescream Nov 22 '12 at 18:35
  • @eyescream done :) – Phil Hawthorn Nov 22 '12 at 18:41
  • 5
    Another suggestion I often see overlooked is that passing key value pairs to the sobject constructor actually saves script statements. new Visitor__c (Name='John Smith', Identifier__c = 'john@somewhere.com') only uses one script statement, instead of the 3 in your example. – Daniel Blackhall Nov 22 '12 at 20:36
  • Very good point @DanielBlackhall – Phil Hawthorn Nov 22 '12 at 20:42
  • 1
    Yes, good point - no one else noticed :D. Edited. – Phil Hawthorn Feb 15 '16 at 18:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.