+ Start a Discussion
dfiredfire 

Detail won't accept Master Id - DMLException

I have a PersonAccount Student which has a Detail custom Object Date, which is a list of the date the student entered and left. I create the student and insert it no problem. But when I try to add the student id which is the Master to the Date's student field and insert, I get the following DML Exception error:

 

System.DmlException: Insert failed. First exception on row 0; first error: FIELD_INTEGRITY_EXCEPTION, Student: id value of incorrect type: 001T000000h4YlVIAU: [Student__c]

 

Here is the controller:

public with sharing class studentApplicationController {

// Non-Object VF Fields
public String lastname { get; set; }
public String firstName { get; set; }
public String salutation { get; set; }

// Object Variable
Account student;
Date__c startdate;

// Other Variables
String submittedPageURL = '';

// util methods
RecordType getPersonAccountRecordTypeId() {
return [select id,name,sobjectType,ispersontype from recordType where ispersontype=true and sobjectType='account' limit 1];
}

// Getters
public Account getStudent() {
if(student == null) {
RecordType recType = getPersonAccountRecordTypeId();
student = new Account(recordtypeid=recType.id);
//student = new Account();
}
return student;
}

public Date__c getStartDate() {
if(startdate == null) {
startdate = new Date__c(status__c='Entered - Non-Academic');
}
return startdate;
}

// Save the application into Salesforce
public PageReference save() {

student.lastname = lastname;
student.firstname = firstname;
student.salutation = salutation;
insert student;

System.debug('Student Id is: '+student.id);
startdate.student__c = student.id;
insert startdate;

PageReference submittedPage = new PageReference(submittedPageURL);
submittedPage.setRedirect(true);
return submittedPage;
}
}

 

According to the debug, the student does have a valid id, so it's not a null value issue.

 

Here is the test code:

 

@isTest
private class StudentApplicationControllerTest {

static testMethod void testController() {
studentApplicationController sac = new StudentApplicationController();
sac.getStudent();
sac.firstName = 'Unit';
sac.lastname = 'Test';
sac.salutation = 'Mr.';

sac.getStartDate().Date__c = Date.newInstance(2, 25, 2011);

sac.save();
}
}

 

 

I get the same error when trying from my VF page.

 

I am not using queues. But the Account is a person account.

 

Any help would be greatly appreciated.

 

 

Best Answer chosen by Admin (Salesforce Developers) 
dfiredfire

I figured out the problem. Complicated because of Person Account. A PA has 2 ids, one for the account side and one for the contact side. The m-d field to student was connect to the contact side of the PA and the id I was trying to pass was for the account side.

 

I modified the code to the following and I got past that error

 

 startdate.student__c = student.PersonContactId;

 

However, the personcontactid is coming back null, so I guess I'll have to run a soql query to get it.

 

All Answers

MrTheTylerMrTheTyler

I think the error is at 

 

startdate.student__c = student.id;

You are trying to put an id for an account object into your custom field student__c.  Now I don't know how you have defined this field within your Date__c object but the debug log is saying that the student__c field is not defined as an account.  My guess is that you will want this student__c field to be a lookup to an account.

 

 

Cheers,

 

Tyler

 

dfiredfire

 

Date__c.student__c is a master-detail field to student which is a person account. I figured for a m-d or lookup field I just set the id of the record I want in the master or lookup field as the value of the field in the detail, but maybe not.

 

So how do I set a master field in the detail in apex?

 

Thanks for the reply.

 

dfiredfire

I figured out the problem. Complicated because of Person Account. A PA has 2 ids, one for the account side and one for the contact side. The m-d field to student was connect to the contact side of the PA and the id I was trying to pass was for the account side.

 

I modified the code to the following and I got past that error

 

 startdate.student__c = student.PersonContactId;

 

However, the personcontactid is coming back null, so I guess I'll have to run a soql query to get it.

 

This was selected as the best answer
MrTheTylerMrTheTyler

You are correct in that you would just set the field value to the id of the record.  I've not dealt with person account record types in my organization but a cursory glance at the online help files led me to find this little morsel of knowledge

 

 

"Record types are person account record types if the Account field IsPersonAccount is set to true"

 

 

And the IsPersonAccount property is a read-only so you'll have to figure out how to declare a new account object with the IsPersonAccount value set to true.  One way I saw in browsing the docs was by using the site class method 

 

 

createPersonAccountPortalUser(sObject user,String ownerId, String password)

 

 

 

http://www.salesforce.com/us/developer/docs/apexcode/index_Left.htm#StartTopic=Content/apex_classes_sites.htm?SearchType=Stem

https://na1.salesforce.com/help/doc/en/salesforce_B2C_implementation_guide.pdf

http://www.salesforce.com/us/developer/docs/api/Content/sforce_api_guidelines_personaccounts.htm#topic-title

 

 

Cheers,

 

Tyler

MrTheTylerMrTheTyler

cool.  Glad it worked out for you.  :smileyhappy:

dfiredfire

I am writing this more as an FYI, to any other developers using Person Accounts. Hopefully you will find this post. :smileyhappy:

 

Person Accounts can be somewhat confusing as they are really a synthesis of an account and a contact record type. I noticed when using the data loader that there were 2 ids for each record. One is an Account id, and the other a Contact id. This is very important to keep straight, as I have learned, since sometimes you need to use the account id, such as when updating a record via the data loader or web-based import. Other times you need the contact id, like now when I had a lookup to the contact side of the person account.

 

Unfortunately there is relatively little documentation on developing with person accounts. But here are some tidbits to help.

 

1) To create a person account, either put a value for the lastname field in your constructor or find the PA record type and set that in your constructor. Since I didn't yet know the last name at the time of field instanciation, I went with the record type route. Here is the code I used:

 

 

// util helper method to get the Person Account Record Type   
RecordType getPersonAccountRecordTypeId() {
return [select id,name,sobjectType,ispersontype from recordType where ispersontype=true and sobjectType='account' limit 1];
}

// Getters
public Account getStudent() {
if(student == null) {
RecordType recType = getPersonAccountRecordTypeId();
student = new Account(recordtypeid=recType.id);
}
return student;
}

 

 

The next snag I encountered was when I wanted to create a custom obj which was a detail to the Student Person Account. When trying to set the id for the lookup to the master record, I initially put in the ID for the student record. This is all mentioned above (as it was the reason for the post in the first place) put I am placing it all here in one place for easy reference.

 

The problem with using the id for the student is that it is the Account ID for the Person Account and the master-detail relationship was to the Contact side of the Person Account. So I needed to use the personContactId as the reference for the lookup. Of course, to get this you need to query for it. Here is the code:

 

 

    Id getContactId() {
return [select id,PersonContactId from Account where id=:student.id][0].id;
}

public PageReference save() {

student.lastname = lastname;
student.firstname = firstname;
student.salutation = salutation;
insert student;

Id cid = getContactId();

startdate.student__c = cid;
insert startdate;

PageReference submittedPage = new PageReference(submittedPageURL);
submittedPage.setRedirect(true);
return submittedPage;
}

 

I hope this helps other people.

 

 

dfiredfire

 

Whoops! Typo should be


Id getContactId() {
return [select id,PersonContactId from Account where id=:student.id][0].personContactId;
}