Handling null values in protobuffers

Disclaimer: Answer from a Googler using protobufs on a daily basis. I’m by no means representing Google in any way.

  1. Name your proto Person instead of PersonProto or ProtoPerson. Compiled protobufs are just class definitions specified by the language you are using, with some improvements. Adding “Proto” is extra verbosity.
  2. Use YourMessage.hasYourField() instead of YourMessage.getYourField() != null. Default value for protobuf string is an empty string, which does NOT equal to null. Whereas, no matter whether your field is unset or cleared or empty string, .hasYourField() always returns false. See default values for common protobuf field types.
  3. You’ve probably known, but I wanna say explicitly: Don’t programmatically set a protobuf field to null. Even for outside of protobuf, null causes all sorts of problems. Use .clearYourField() instead.
  4. Person.Builder class does NOT have a .newBuilder() method. Person class does. Understand the Builder Pattern like this: You create a new builder only if you do not have it yet.

A rewrite of your protobuf:

message Person {
  optional string first_name = 1;
  optional string last_name = 2;
  optional string address_1 = 3;
}

A rewrite of your logic:

Person thatPerson = Person.newBuilder()
    .setFirstName("Aaa")
    .setLastName("Bbb")
    .setAddress1("Ccc")
    .build();

Person.Builder thisPersonBuilder = Person.newBuilder()

if (thatPerson.hasFirstName()) {
  thisPersonBuilder.setFirstName(thatPerson.getFirstName());
}

if (thatPerson.hasLastName()) {
  thisPersonBuilder.setLastName(thatPerson.getLastName());
}

if (thatPerson.hasAddress1()) {
  thisPersonBuilder.setAddress1(thatPerson.getAddress1());
}

Person thisPerson = thisPersonBuilder.build();

And if thatPerson is a person object that you created that has attribute values that could be an empty string, empty spaces or null, then I’d recommend using Guava’s Strings library:

import static com.google.common.base.Strings.nullToEmpty;

Person.Builder thisPersonBuilder = Person.newBuilder()

if (!nullToEmpty(thatPerson.getFirstName()).trim().isEmpty()) {
  thisPersonBuilder.setFirstName(thatPerson.getFirstName());
}

if (!nullToEmpty(thatPerson.hasLastName()).trim().isEmpty()) {
  thisPersonBuilder.setLastName(thatPerson.getLastName());
}

if (!nullToEmpty(thatPerson.hasAddress1()).trim().isEmpty()) {
  thisPersonBuilder.setAddress1(thatPerson.getAddress1());
}

Person thisPerson = thisPersonBuilder.build();

Leave a Comment

Hata!: SQLSTATE[HY000] [1045] Access denied for user 'divattrend_liink'@'localhost' (using password: YES)