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??
Disclaimer: Answer from a Googler using protobufs on a daily basis. I'm by no means representing Google in any way.
Person
instead ofPersonProto
orProtoPerson
. Compiled protobufs are just class definitions specified by the language you are using, with some improvements. Adding "Proto" is extra verbosity.YourMessage.hasYourField()
instead ofYourMessage.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:
A rewrite of your logic:
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'sStrings
library:For proto 3: wrappers.proto support nullable values: string(StringValue), int(Int32Value), bool(BoolValue) and etc
There's no easy solution to this. I'd recommend just dealing with the null checks. But if you really want to get rid of them, here are a couple ideas:
setOrClearFoo()
methods to each Java class. The Java code generator provides insertion points for this (see the end of that page).get*()
methods ofp
, call each one, check fornull
, and then call theset*()
method ofbuilder
if non-null. This will have the added advantage that you won't have to update your copy code every time you add a new field, but it will be much slower than writing code that copies each field explicitly.