/**
   * Update the married status of a new user record.
   *
   * <p>This method demonstrates updating both a UserProfileModel and a UserActionsModel with a
   * single HBase request using the composite dao. It performs a get/update/put operation, which is
   * protected by the check_conflict field on UserProfileModel from colliding with another
   * get/update/put operation.
   *
   * @param firstName The first name of the user we are updating
   * @param lastName The last name of the user we are updating
   * @param married True if this person is married. Otherwise false.
   */
  public void updateUserProfile(String firstName, String lastName, boolean married) {
    // Get the timestamp we'll use to set the value of the profile_updated
    // action.
    long ts = System.currentTimeMillis();

    // Construct the key we'll use to fetch the user.
    PartitionKey key =
        userProfileActionsDao.getPartitionStrategy().partitionKey(lastName, firstName);

    // Get the profile and actions entity from the composite dao.
    UserProfileActionsModel profileActionsModel = userProfileActionsDao.get(key);

    // Updating the married status is hairy since our avro compiler isn't setup
    // to compile setters for fields. We have to construct a clone through the
    // builder.
    UserProfileActionsModel updatedProfileActionsModel =
        UserProfileActionsModel.newBuilder(profileActionsModel)
            .setUserProfileModel(
                UserProfileModel.newBuilder(profileActionsModel.getUserProfileModel())
                    .setMarried(married)
                    .build())
            .build();
    // Since maps are mutable, we can update the actions map without having to
    // go through the builder like above.
    updatedProfileActionsModel
        .getUserActionsModel()
        .getActions()
        .put("profile_updated", Long.toString(ts));

    if (!userProfileActionsDao.put(updatedProfileActionsModel)) {
      // If put returns false, a write conflict occurred where someone else
      // updated the row between the times we did the get and put.
      System.out.println("Updating the user profile failed due to a write conflict");
    }
  }
  /**
   * Create a fresh new user record.
   *
   * <p>This method demonstrates creating both a UserProfileModel and a UserActionsModel atomically
   * in a single row. When creating a user profile, we add the "created" action to the actions map.
   * This shows how we can use the CompositeDao to accomplish this.
   *
   * @param firstName The first name of the user we are creating
   * @param lastName The last name of the user we are creating
   * @param married True if this person is married. Otherwise false.
   */
  public void create(String firstName, String lastName, boolean married) {
    long ts = System.currentTimeMillis();

    UserProfileModel profileModel =
        UserProfileModel.newBuilder()
            .setFirstName(firstName)
            .setLastName(lastName)
            .setMarried(married)
            .setCreated(ts)
            .build();
    UserActionsModel actionsModel =
        UserActionsModel.newBuilder()
            .setFirstName(firstName)
            .setLastName(lastName)
            .setActions(new HashMap<String, String>())
            .build();
    actionsModel.getActions().put("profile_created", Long.toString(ts));

    UserProfileActionsModel profileActionsModel =
        UserProfileActionsModel.newBuilder()
            .setUserProfileModel(profileModel)
            .setUserActionsModel(actionsModel)
            .build();

    if (!userProfileActionsDao.put(profileActionsModel)) {
      // If put returns false, a user already existed at this row
      System.out.println("Creating a new user profile failed due to a write conflict.");
    }
  }