How to Insert Parent record and list of child records in Visualforce

Object Relationships

Object relationships are a special field type that connects two objects together. In Salesforce, there are two main types of object relationships: lookup and master-detail.

Lookup Relationship

A lookup relationship essentially links two objects so that you can “look up” one object from the related items on another object. However, there is no effect on deletion or security. Unlike master-detail fields, lookup fields are not automatically required. When you define a lookup relationship, data from one object can appear as a custom related list on page layouts for the other object. Lookup relationships can be one-to-one (1: 1) or one-to-many (1: n). For example, the Account to Contact relationship is one-to-many because a single account can have many related contacts.

Master-Detail Relationship

The master-detail relationship is a parent-child relationship in which the master object controls certain behaviors of the detail object, like who can view the detail’s data.  In this relationship, one object is the master and another is the detail. The relationships are a bit tighter than the lookup relationship. To learn more, go to the  Trailhead Module on object relationships.

The Account to Contact relationship is an example of a standard relationship in Salesforce that will be used in this post. As written above, the two standard objects – Account and Contact have a lookup relationship.

Consider the one-to-many relationship between Account and Contact,  one Account with many Contact records will be created or inserted using a custom controller in Visualforce.

The form to be used includes the Account object fields and Contact fields.  Most importantly, there will be an AddRow functionality below it to add more set of fields to the form in order to create more records if required in your use case. The layout is attached below.

Below is the Visualforce code:

<apex:page controller="insertParentChildCon">
  function confirmCancel() {
      var isCancel = confirm("Are you sure you wish to cancel?");
      if (isCancel) return true;
     return false;
 <apex:form >
 <apex:pageBlock >
  <apex:pageBlockButtons location="top" >
  <apex:commandButton action="{!Save}" value="Save"/>
  <apex:commandButton action="{!cancel}" value="Cancel" 
                              onclick="return confirmCancel()" immediate="true" id="cancel"/>
  <apex:pageBlockSection columns="2">
       <apex:inputField value="{!account.Name}"/>
      <apex:inputField value="{!account.Phone}"/>
      <apex:inputField value="{!account.Website}"/>
      <apex:inputField value="{!account.Industry}"/>
 <apex:pageBlockSection title="Add Contacts ti the Account" >
     <apex:repeat value="{!contList}" var="ct" id="table" >
      <apex:inputField value="{!ct.LastName}"/>
      <apex:inputField value="{!ct.Firstname}"/>
      <apex:inputField value="{!ct.Title}"/>
      <apex:inputField value="{!}"/>
 <apex:commandButton value="Add Row" Action="{!AddRow}" immediate="true" id="button"/> 

The Controller for the Visualforce Code:

public class insertParentChildCon { 
    public Account getAccount() {
        return account;

   public List<Account> acctList {get;set;}    
    Account account {get;set;}   
    public List<Contact> contList {get; set;}
      public insertParentChildCon() {
               account= new Account();
                contList = new List<Contact>();
    public PageReference AddRow() {
    contList.add(new Contact());
    return null;
 public PageReference cancel() {
            PageReference acctPage = new ApexPages.StandardController(account).view();
            return acctPage; 
 public PageReference Save() {
       upsert account;
       List<Contact> conts = new List<Contact>();
       if(account != null) {
        for(Contact c : contlist) {
         c.AccountId = account.Id;
       if(conts != null) { 
       upsert contList;
       return null;

In this controller, the AddRow method is not the same as the one in my post Adding row functionality to Existing ones on Visualforce Page. While that one used a wrapper class, this one used a shorter method. This AddRow method is included in the class constructor to account for the default form on the layout. If you comment out the method in the constructor,  you will have to click the AddRow even for the first set of forms.

For the post, I added one Account – called ZenMart and added two Contact records and clicked Save button. The output is attached below

If you have any question, sent me an email

Thanks for visiting