I am working on something which fetches data from database and constructs protobuff message. Given the possibility that null values can be fetched from the database for certain fields , I will get Null-pointer exception while trying to construct the protobuff message. Getting to know that null is not supported in protobuffs from the thread http://code.google.com/p/protobuf/issues/detail?id=57, I am wondering whether the only other way to handle NPE getting thrown is to insert manual checks into the java file corresponding to the proto like below!
message ProtoPerson{ optional string firstName = 1; optional string lastName = 2; optional string address1 = 3; } ProtoPerson.Builder builder = ProtoPerson.Builder.newBuilder(); if (p.getFirstName() != null) builder.setFirstName(p.getFirstName()); if (p.getLastName() != null) builder.setLastName(p.getLastName()); if (p.getAddress1() != null) builder.setAddress1(p.getAddress1()); ...
So can someone please clarify whether there is any other possible efficient way to handle the null values during protobuff construction??
Protobuf treats strings as primitive types and therefore they can not be null. Instead of checking if the string is not null use standard libraries, like apache commons, to check if the string is not blank. This is clear that the value will be inserted if the value is not blank.
For bool s, the default value is false. For numeric types, the default value is zero. For enums , the default value is the first value listed in the enum's type definition. This means care must be taken when adding a value to the beginning of an enum value list.
protobuf. Empty states: A generic empty message that you can re-use to avoid defining duplicated empty messages in your APIs. A typical example is to use it as the request or the response type of an API method.
Disclaimer: Answer from a Googler using protobufs on a daily basis. I'm by no means representing Google in any way.
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.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.null
. Even for outside of protobuf, null
causes all sorts of problems. Use .clearYourField()
instead.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();
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With