1. Define custom entity
    Entity API provides hooks to extend and add new entities. There are lot of options available in this hook, but for now we will consider only the required options in the hook.

Lets create a new entity named "events" with a bundle "hackathon".

/*
 * Implements hook_entity_info()
 */
function mymodule_entity_info() {
  $info = array();
  $info['events'] = array(
    'label' => t('Events'),
    'base table' => 'events', // Table tobe added in hook_schema.
    'entity keys' => array(
      // Database field where bundle types of entities are saved.
      'bundle' => 'type',
    ),
    'entity class' => 'Entity',
    'controller class' => 'EntityAPIController',
    // Is it possible to attach fields to bundles.
    'fieldable' => TRUE,
    // Describe bundles of this entity.
    'bundles' => array(
      'hackathon' => array(
        'label' => t('Event for Hackathon'),
      ),),
  );
  return $info;
}
  1. Add database table for custom with default fields
    Next thing we need to do is add database table fort the entity i.e add schema for creating new database. Add the following code in your .install file
function mymodule_schema() {
  $schema['events'] = array(
    'description' => 'The base table events.',
    'fields' => array(
      'id' => array(
        'description' => 'The primary identifier.',
        'type' => 'serial',
        'unsigned' => TRUE,
        'not null' => TRUE,
      ),
      'title' => array(
        'description' => 'Event title',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
      'date' => array(
        'description' => 'The Unix timestamp of event',
        'type' => 'int',
        'not null' => TRUE,
        'default' => 0,
      ),
      'type' => array(
        'description' => 'Type of bundle',
        'type' => 'varchar',
        'length' => 255,
        'not null' => TRUE,
        'default' => '',
      ),
    ),
    'primary key' => array('id'),
  );
  return $schema;
}
  1. Attach new fields to entity
    For adding custom fileds create a function with field data and field instance. And in hook_update_N() call the function to create new fields

Add the following function in .module or .inc file

function mymodule_field_data() {
  $fields = array(
    'place' => array(
      'field' => array(
        'field_name' => 'field_place',
        'entity_types' => array('events'),
        'cardinality' => 1,
        'type' => 'text',
        'settings' => array('max_length' => 255),
      ),
      'instance1' => array(
        'field_name' => 'field_place',
        'label' => t('Hackthon'),
        'entity_type' => 'events',
        'bundle' => 'hackathon',
        'description' => t('Place where hackthon takes place.'),
      ),
    ),
  );
  return $fields;
}

In .install add hook_update_N and call the above function

function mymodule_update_7001(){
  // Define field and field instances.
  $fields = mymodule_field_data();
  foreach ($fields as $field_data) {
    $field = $field_data['field'];
    // Create field if not exists.
    if (!field_read_field($field['field_name'], array('include_inactive' => TRUE))){
      field_create_field($field);
    }
    $instance1 = $field_data['instance1'];
    // Create field instance if not exists.
    if (!field_read_instance($instance1['entity_type'], $instance1['field_name'],         $instance1['bundle'], array('include_inactive' => TRUE))) {
        field_attach_create_bundle('events', 'hackathin');
        field_create_instance($instance1);
      }
  }
}
  1. Save entity data with attached fields
function mymodule_save_entities() {
  $entity = entity_get_controller('events')->create();
  // Save entity properties.
  $entity->title = 'Hackathon 1';
  $entity->date = '1/1/2018';
  $entity->type = 'hackathon'; // set the bundle
  $language = isset($user->language)? $user->language : 'und';
  
  // Save attached fields.
  $entity->field_place = 'Delhi';
  entity_save('events', $entity);
}