You are viewing a plain text version of this content. The canonical link for it is here.
Posted to dev@avro.apache.org by Niels Basjes <Ni...@basjes.nl> on 2014/11/26 18:28:49 UTC

Always getting a value...

Hi,

I have a Java project where I'm using Avro as the serialization technology.
I have a deep nested structure and many fields are optional.

Because of the 'random' nature of my application I want to be able to
simply 'set' a value in that tree easily.

So I want to have a setter in my class that looks like this (Assume
myStruct is an instance of the 'root' class generated by Avro):

public void setSomething(String value) {
    myStruct
            .getFoo()
            .getBar()
            .getOne()
            .getOther()
            .setSomething(value);
}

The 'problem' I ran into is that any of the 4 get methods can return a null
value so the code I have to write is really huge.
For every step in this method I have to build null checks and create the
underlying instance if it is null.
I already started writing helper methods to do this for parts of my tree.

To solve this in a way that makes this code readable I came up with the
following which I want to propose to you guys (before I start working on a
patch).

My idea is to generate a new 'get' method in addition to the existing
normal get method for the regular instance of the class.

So in addition to the

public void getFoo() {
    return foo;
}

I propose to generate something like this as well

public void getAlwaysFoo() {
    if (foo == null) {
        setFoo(Foo.newBuilder().build());
    }
    return foo;
}

This way the automatically created instance immediately has all the
defaults I have defined.

Assuming this naming my code will be readable because it will look like
this:
public void setSomething(String value) {
    myStruct
            .getAlwaysFoo()
            .getAlwaysBar()
            .getAlwaysOne()
            .getAlwaysOther()
            .setSomething(value);
}

I can create this same effect in my own project code.
But having this automatically generated by the Avro engine would make life
a lot easier.

Is this an idea you guys would consider to have in the main (Java)
generated code base?
If so, is the 'getAlways' prefix sensible?

-- 
Best regards

Niels Basjes

Re: Always getting a value...

Posted by Niels Basjes <Ni...@basjes.nl>.
I uploaded a patch for AVRO-1614 and AVRO-1616 (just an update to the
.gitignore).

It seems that there is no automatic pickup by Jenkins configured (like with
Hadoop and HBase).

How do I proceed in getting your feedback on these patches and getting them
reviewed and if possible comitted?

Thanks.

Niels Basjes

On Mon, Dec 1, 2014 at 6:05 PM, Niels Basjes <Ni...@basjes.nl> wrote:

> Hi,
>
> I realized over the weekend that the Builder instances do support an
> 'incomplete' schema and this is validated at the time the build() is called.
> Based upon that I redid the patch today so that in a Builder in addition
> to the actual value of a field there is now also a "Builder" field for that
> field possible.
> If that is used then you can have the incomplete form of the sub-schema in
> a Builder.
> So for any Builder instance there is a getFooBuilder() that either returns
> the existing or creates a new Builder instance for the Foo field if such a
> builder is supported.
>
> As a consequence:
> - schema validation is postponed until the actual build() is called.
> - for the fields where this Builder is used the actual build() call
> becomes recursive.
>
> So in my testing code I can now do this:
>
>
> *    Measurement.Builder measurementBuilder = Measurement.newBuilder();*
>
> *    measurementBuilder*
> *            .getTransportBuilder()*
> *              .getConnectionBuilder()*
> *                .getNetworkConnectionBuilder()*
> *                  .setNetworkAddress("127.0.0.1")*
> *                  .setNetworkType(NetworkType.IPv4);*
>
> *    Measurement measurement = measurementBuilder.build();*
>
> Open question: I have not seen unit tests that validate the generated Java
> code yet. How to approach this?
>
> Niels Basjes
>
>
> On Thu, Nov 27, 2014 at 5:37 PM, Niels Basjes <Ni...@basjes.nl> wrote:
>
>> Hi,
>>
>> To see how it would work I simply wrote the patch and played in my
>> environment with the effects on the generated Java code.
>> [ I created a Jira issue and attached this draft patch to it:
>> https://issues.apache.org/jira/browse/AVRO-1614 ]
>>
>> The idea works but I also found that for my usecase it is not very
>> pleasant to work with.
>>
>> Assume this example again:
>>
>> public void setSomething(String value) {
>>     myStruct
>>             .getAlwaysFoo()
>>             .getAlwaysBar()
>>             .getAlwaysOne()
>>             .getAlwaysOther()
>>             .setSomething(value);
>> }
>>
>> The main problem is that in order to do .getAlwaysOne() I MUST define
>> ALL fields of that type with a default value.
>> What I don;t like about that is that I want the schema definition to
>> enforce the fact that some fields are mandatory.
>> By adding a default value to 'everything' I lose that capability of AVRO
>> ... which I don't want.
>>
>> At this point in time the only workaround this (for me major) issue is by
>> introducing something where I can do something like having a 'tree of
>> incomplete Builders' and when I say 'build()' to the top one it will build
>> the entire tree.
>>
>> Any thoughts?
>> Do you guy think there is a need/usecase for this idea (so I leave the
>> issue open) or shall I simply close AVRO-1614 with a 'Won't fix'?
>>
>> Niels Basjes
>>
>>
>>
>> On Thu, Nov 27, 2014 at 1:37 AM, Doug Cutting <cu...@apache.org> wrote:
>>
>>> On Wed, Nov 26, 2014 at 2:33 PM, svante karlsson <sa...@csi.se> wrote:
>>> > I'm not sure that works for avro where null is used for an optional
>>> field.
>>>
>>> It should work.  If it doesn't, it's a bug.  For example:
>>>
>>> record Foo {
>>>   union {string, null} name = "default";
>>> }
>>>
>>> record Bar {
>>>   union {Foo, null} foo = {"name" = "non-default"};
>>> }
>>>
>>> Default values in IDL are JSON format.
>>>
>>> Doug
>>>
>>
>>
>>
>> --
>> Best regards / Met vriendelijke groeten,
>>
>> Niels Basjes
>>
>
>
>
> --
> Best regards / Met vriendelijke groeten,
>
> Niels Basjes
>



-- 
Best regards / Met vriendelijke groeten,

Niels Basjes

Re: Always getting a value...

Posted by Niels Basjes <Ni...@basjes.nl>.
Hi,

I realized over the weekend that the Builder instances do support an
'incomplete' schema and this is validated at the time the build() is called.
Based upon that I redid the patch today so that in a Builder in addition to
the actual value of a field there is now also a "Builder" field for that
field possible.
If that is used then you can have the incomplete form of the sub-schema in
a Builder.
So for any Builder instance there is a getFooBuilder() that either returns
the existing or creates a new Builder instance for the Foo field if such a
builder is supported.

As a consequence:
- schema validation is postponed until the actual build() is called.
- for the fields where this Builder is used the actual build() call becomes
recursive.

So in my testing code I can now do this:


*    Measurement.Builder measurementBuilder = Measurement.newBuilder();*

*    measurementBuilder*
*            .getTransportBuilder()*
*              .getConnectionBuilder()*
*                .getNetworkConnectionBuilder()*
*                  .setNetworkAddress("127.0.0.1")*
*                  .setNetworkType(NetworkType.IPv4);*

*    Measurement measurement = measurementBuilder.build();*

Open question: I have not seen unit tests that validate the generated Java
code yet. How to approach this?

Niels Basjes


On Thu, Nov 27, 2014 at 5:37 PM, Niels Basjes <Ni...@basjes.nl> wrote:

> Hi,
>
> To see how it would work I simply wrote the patch and played in my
> environment with the effects on the generated Java code.
> [ I created a Jira issue and attached this draft patch to it:
> https://issues.apache.org/jira/browse/AVRO-1614 ]
>
> The idea works but I also found that for my usecase it is not very
> pleasant to work with.
>
> Assume this example again:
>
> public void setSomething(String value) {
>     myStruct
>             .getAlwaysFoo()
>             .getAlwaysBar()
>             .getAlwaysOne()
>             .getAlwaysOther()
>             .setSomething(value);
> }
>
> The main problem is that in order to do .getAlwaysOne() I MUST define ALL
> fields of that type with a default value.
> What I don;t like about that is that I want the schema definition to
> enforce the fact that some fields are mandatory.
> By adding a default value to 'everything' I lose that capability of AVRO
> ... which I don't want.
>
> At this point in time the only workaround this (for me major) issue is by
> introducing something where I can do something like having a 'tree of
> incomplete Builders' and when I say 'build()' to the top one it will build
> the entire tree.
>
> Any thoughts?
> Do you guy think there is a need/usecase for this idea (so I leave the
> issue open) or shall I simply close AVRO-1614 with a 'Won't fix'?
>
> Niels Basjes
>
>
>
> On Thu, Nov 27, 2014 at 1:37 AM, Doug Cutting <cu...@apache.org> wrote:
>
>> On Wed, Nov 26, 2014 at 2:33 PM, svante karlsson <sa...@csi.se> wrote:
>> > I'm not sure that works for avro where null is used for an optional
>> field.
>>
>> It should work.  If it doesn't, it's a bug.  For example:
>>
>> record Foo {
>>   union {string, null} name = "default";
>> }
>>
>> record Bar {
>>   union {Foo, null} foo = {"name" = "non-default"};
>> }
>>
>> Default values in IDL are JSON format.
>>
>> Doug
>>
>
>
>
> --
> Best regards / Met vriendelijke groeten,
>
> Niels Basjes
>



-- 
Best regards / Met vriendelijke groeten,

Niels Basjes

Re: Always getting a value...

Posted by Niels Basjes <Ni...@basjes.nl>.
Hi,

To see how it would work I simply wrote the patch and played in my
environment with the effects on the generated Java code.
[ I created a Jira issue and attached this draft patch to it:
https://issues.apache.org/jira/browse/AVRO-1614 ]

The idea works but I also found that for my usecase it is not very pleasant
to work with.

Assume this example again:

public void setSomething(String value) {
    myStruct
            .getAlwaysFoo()
            .getAlwaysBar()
            .getAlwaysOne()
            .getAlwaysOther()
            .setSomething(value);
}

The main problem is that in order to do .getAlwaysOne() I MUST define ALL
fields of that type with a default value.
What I don;t like about that is that I want the schema definition to
enforce the fact that some fields are mandatory.
By adding a default value to 'everything' I lose that capability of AVRO
... which I don't want.

At this point in time the only workaround this (for me major) issue is by
introducing something where I can do something like having a 'tree of
incomplete Builders' and when I say 'build()' to the top one it will build
the entire tree.

Any thoughts?
Do you guy think there is a need/usecase for this idea (so I leave the
issue open) or shall I simply close AVRO-1614 with a 'Won't fix'?

Niels Basjes



On Thu, Nov 27, 2014 at 1:37 AM, Doug Cutting <cu...@apache.org> wrote:

> On Wed, Nov 26, 2014 at 2:33 PM, svante karlsson <sa...@csi.se> wrote:
> > I'm not sure that works for avro where null is used for an optional
> field.
>
> It should work.  If it doesn't, it's a bug.  For example:
>
> record Foo {
>   union {string, null} name = "default";
> }
>
> record Bar {
>   union {Foo, null} foo = {"name" = "non-default"};
> }
>
> Default values in IDL are JSON format.
>
> Doug
>



-- 
Best regards / Met vriendelijke groeten,

Niels Basjes

Re: Always getting a value...

Posted by Doug Cutting <cu...@apache.org>.
On Wed, Nov 26, 2014 at 2:33 PM, svante karlsson <sa...@csi.se> wrote:
> I'm not sure that works for avro where null is used for an optional field.

It should work.  If it doesn't, it's a bug.  For example:

record Foo {
  union {string, null} name = "default";
}

record Bar {
  union {Foo, null} foo = {"name" = "non-default"};
}

Default values in IDL are JSON format.

Doug

Re: Always getting a value...

Posted by svante karlsson <sa...@csi.se>.
>You can instead list the non-null type first and give a default appropriate
>for the field type. I'd be surprised if the IDL couldn't also do this.

I'm not sure that works for avro where null is used for an optional field.



2014-11-26 23:28 GMT+01:00 Sean Busbey <bu...@cloudera.com>:

> I usually use Schemas directly rather than IDL, so apologies if some of
> this doesn't map directly.
>
> In a Schema with an optional field, or really any union, the default value
> has to be of the first mentioned type. For optional fields this usually
> means making the first value the null type and the default value null.
>
> You can instead list the non-null type first and give a default appropriate
> for the field type. I'd be surprised if the IDL couldn't also do this.
>
> On Wed, Nov 26, 2014 at 3:56 PM, Niels Basjes <Ni...@basjes.nl> wrote:
>
> > Yes, the builders would do that for mandatory (= non-null) fields.
> >
> > The schemas I'm using have a lot of this pattern
> >
> > record Thing {
> >   union { null, Foo } optionalFoo;
> >
> >   union { null, Bar } optionalBar;
> >
> > }
> >
> > record Bar {
> >   union { null, Blabla } optionalBlabla;
> > }
> >
> > etc.
> >
> > So creating a record with a simple Thing.newBuilder().build() would still
> > yield null values for both optionalFoo and optionalBar.
> >
> >
> >
> > On Wed, Nov 26, 2014 at 8:58 PM, Sean Busbey <bu...@cloudera.com>
> wrote:
> >
> > > What does an example schema look like in this case?
> > >
> > > Shouldn't the extant builders give you this behavior if you've made the
> > > default for the optional fields non-null?
> > >
> > > --
> > > Sean
> > > On Nov 26, 2014 11:34 AM, "Niels Basjes" <Ni...@basjes.nl> wrote:
> > >
> > > > Oops,
> > > > That should be
> > > >      public Foo getFoo()
> > > > and
> > > >      public Foo getAlwaysFoo()
> > > > ofcourse
> > > >
> > > > On Wed, Nov 26, 2014 at 6:28 PM, Niels Basjes <Ni...@basjes.nl>
> wrote:
> > > >
> > > > > Hi,
> > > > >
> > > > > I have a Java project where I'm using Avro as the serialization
> > > > technology.
> > > > > I have a deep nested structure and many fields are optional.
> > > > >
> > > > > Because of the 'random' nature of my application I want to be able
> to
> > > > > simply 'set' a value in that tree easily.
> > > > >
> > > > > So I want to have a setter in my class that looks like this (Assume
> > > > > myStruct is an instance of the 'root' class generated by Avro):
> > > > >
> > > > > public void setSomething(String value) {
> > > > >     myStruct
> > > > >             .getFoo()
> > > > >             .getBar()
> > > > >             .getOne()
> > > > >             .getOther()
> > > > >             .setSomething(value);
> > > > > }
> > > > >
> > > > > The 'problem' I ran into is that any of the 4 get methods can
> return
> > a
> > > > > null value so the code I have to write is really huge.
> > > > > For every step in this method I have to build null checks and
> create
> > > the
> > > > > underlying instance if it is null.
> > > > > I already started writing helper methods to do this for parts of my
> > > tree.
> > > > >
> > > > > To solve this in a way that makes this code readable I came up with
> > the
> > > > > following which I want to propose to you guys (before I start
> working
> > > on
> > > > a
> > > > > patch).
> > > > >
> > > > > My idea is to generate a new 'get' method in addition to the
> existing
> > > > > normal get method for the regular instance of the class.
> > > > >
> > > > > So in addition to the
> > > > >
> > > > > public void getFoo() {
> > > > >     return foo;
> > > > > }
> > > > >
> > > > > I propose to generate something like this as well
> > > > >
> > > > > public void getAlwaysFoo() {
> > > > >     if (foo == null) {
> > > > >         setFoo(Foo.newBuilder().build());
> > > > >     }
> > > > >     return foo;
> > > > > }
> > > > >
> > > > > This way the automatically created instance immediately has all the
> > > > > defaults I have defined.
> > > > >
> > > > > Assuming this naming my code will be readable because it will look
> > like
> > > > > this:
> > > > > public void setSomething(String value) {
> > > > >     myStruct
> > > > >             .getAlwaysFoo()
> > > > >             .getAlwaysBar()
> > > > >             .getAlwaysOne()
> > > > >             .getAlwaysOther()
> > > > >             .setSomething(value);
> > > > > }
> > > > >
> > > > > I can create this same effect in my own project code.
> > > > > But having this automatically generated by the Avro engine would
> make
> > > > life
> > > > > a lot easier.
> > > > >
> > > > > Is this an idea you guys would consider to have in the main (Java)
> > > > > generated code base?
> > > > > If so, is the 'getAlways' prefix sensible?
> > > > >
> > > > > --
> > > > > Best regards
> > > > >
> > > > > Niels Basjes
> > > > >
> > > >
> > > >
> > > >
> > > > --
> > > > Best regards / Met vriendelijke groeten,
> > > >
> > > > Niels Basjes
> > > >
> > >
> >
> >
> >
> > --
> > Best regards / Met vriendelijke groeten,
> >
> > Niels Basjes
> >
>
>
>
> --
> Sean
>

Re: Always getting a value...

Posted by Sean Busbey <bu...@cloudera.com>.
I usually use Schemas directly rather than IDL, so apologies if some of
this doesn't map directly.

In a Schema with an optional field, or really any union, the default value
has to be of the first mentioned type. For optional fields this usually
means making the first value the null type and the default value null.

You can instead list the non-null type first and give a default appropriate
for the field type. I'd be surprised if the IDL couldn't also do this.

On Wed, Nov 26, 2014 at 3:56 PM, Niels Basjes <Ni...@basjes.nl> wrote:

> Yes, the builders would do that for mandatory (= non-null) fields.
>
> The schemas I'm using have a lot of this pattern
>
> record Thing {
>   union { null, Foo } optionalFoo;
>
>   union { null, Bar } optionalBar;
>
> }
>
> record Bar {
>   union { null, Blabla } optionalBlabla;
> }
>
> etc.
>
> So creating a record with a simple Thing.newBuilder().build() would still
> yield null values for both optionalFoo and optionalBar.
>
>
>
> On Wed, Nov 26, 2014 at 8:58 PM, Sean Busbey <bu...@cloudera.com> wrote:
>
> > What does an example schema look like in this case?
> >
> > Shouldn't the extant builders give you this behavior if you've made the
> > default for the optional fields non-null?
> >
> > --
> > Sean
> > On Nov 26, 2014 11:34 AM, "Niels Basjes" <Ni...@basjes.nl> wrote:
> >
> > > Oops,
> > > That should be
> > >      public Foo getFoo()
> > > and
> > >      public Foo getAlwaysFoo()
> > > ofcourse
> > >
> > > On Wed, Nov 26, 2014 at 6:28 PM, Niels Basjes <Ni...@basjes.nl> wrote:
> > >
> > > > Hi,
> > > >
> > > > I have a Java project where I'm using Avro as the serialization
> > > technology.
> > > > I have a deep nested structure and many fields are optional.
> > > >
> > > > Because of the 'random' nature of my application I want to be able to
> > > > simply 'set' a value in that tree easily.
> > > >
> > > > So I want to have a setter in my class that looks like this (Assume
> > > > myStruct is an instance of the 'root' class generated by Avro):
> > > >
> > > > public void setSomething(String value) {
> > > >     myStruct
> > > >             .getFoo()
> > > >             .getBar()
> > > >             .getOne()
> > > >             .getOther()
> > > >             .setSomething(value);
> > > > }
> > > >
> > > > The 'problem' I ran into is that any of the 4 get methods can return
> a
> > > > null value so the code I have to write is really huge.
> > > > For every step in this method I have to build null checks and create
> > the
> > > > underlying instance if it is null.
> > > > I already started writing helper methods to do this for parts of my
> > tree.
> > > >
> > > > To solve this in a way that makes this code readable I came up with
> the
> > > > following which I want to propose to you guys (before I start working
> > on
> > > a
> > > > patch).
> > > >
> > > > My idea is to generate a new 'get' method in addition to the existing
> > > > normal get method for the regular instance of the class.
> > > >
> > > > So in addition to the
> > > >
> > > > public void getFoo() {
> > > >     return foo;
> > > > }
> > > >
> > > > I propose to generate something like this as well
> > > >
> > > > public void getAlwaysFoo() {
> > > >     if (foo == null) {
> > > >         setFoo(Foo.newBuilder().build());
> > > >     }
> > > >     return foo;
> > > > }
> > > >
> > > > This way the automatically created instance immediately has all the
> > > > defaults I have defined.
> > > >
> > > > Assuming this naming my code will be readable because it will look
> like
> > > > this:
> > > > public void setSomething(String value) {
> > > >     myStruct
> > > >             .getAlwaysFoo()
> > > >             .getAlwaysBar()
> > > >             .getAlwaysOne()
> > > >             .getAlwaysOther()
> > > >             .setSomething(value);
> > > > }
> > > >
> > > > I can create this same effect in my own project code.
> > > > But having this automatically generated by the Avro engine would make
> > > life
> > > > a lot easier.
> > > >
> > > > Is this an idea you guys would consider to have in the main (Java)
> > > > generated code base?
> > > > If so, is the 'getAlways' prefix sensible?
> > > >
> > > > --
> > > > Best regards
> > > >
> > > > Niels Basjes
> > > >
> > >
> > >
> > >
> > > --
> > > Best regards / Met vriendelijke groeten,
> > >
> > > Niels Basjes
> > >
> >
>
>
>
> --
> Best regards / Met vriendelijke groeten,
>
> Niels Basjes
>



-- 
Sean

Re: Always getting a value...

Posted by Niels Basjes <Ni...@basjes.nl>.
Yes, the builders would do that for mandatory (= non-null) fields.

The schemas I'm using have a lot of this pattern

record Thing {
  union { null, Foo } optionalFoo;

  union { null, Bar } optionalBar;

}

record Bar {
  union { null, Blabla } optionalBlabla;
}

etc.

So creating a record with a simple Thing.newBuilder().build() would still
yield null values for both optionalFoo and optionalBar.



On Wed, Nov 26, 2014 at 8:58 PM, Sean Busbey <bu...@cloudera.com> wrote:

> What does an example schema look like in this case?
>
> Shouldn't the extant builders give you this behavior if you've made the
> default for the optional fields non-null?
>
> --
> Sean
> On Nov 26, 2014 11:34 AM, "Niels Basjes" <Ni...@basjes.nl> wrote:
>
> > Oops,
> > That should be
> >      public Foo getFoo()
> > and
> >      public Foo getAlwaysFoo()
> > ofcourse
> >
> > On Wed, Nov 26, 2014 at 6:28 PM, Niels Basjes <Ni...@basjes.nl> wrote:
> >
> > > Hi,
> > >
> > > I have a Java project where I'm using Avro as the serialization
> > technology.
> > > I have a deep nested structure and many fields are optional.
> > >
> > > Because of the 'random' nature of my application I want to be able to
> > > simply 'set' a value in that tree easily.
> > >
> > > So I want to have a setter in my class that looks like this (Assume
> > > myStruct is an instance of the 'root' class generated by Avro):
> > >
> > > public void setSomething(String value) {
> > >     myStruct
> > >             .getFoo()
> > >             .getBar()
> > >             .getOne()
> > >             .getOther()
> > >             .setSomething(value);
> > > }
> > >
> > > The 'problem' I ran into is that any of the 4 get methods can return a
> > > null value so the code I have to write is really huge.
> > > For every step in this method I have to build null checks and create
> the
> > > underlying instance if it is null.
> > > I already started writing helper methods to do this for parts of my
> tree.
> > >
> > > To solve this in a way that makes this code readable I came up with the
> > > following which I want to propose to you guys (before I start working
> on
> > a
> > > patch).
> > >
> > > My idea is to generate a new 'get' method in addition to the existing
> > > normal get method for the regular instance of the class.
> > >
> > > So in addition to the
> > >
> > > public void getFoo() {
> > >     return foo;
> > > }
> > >
> > > I propose to generate something like this as well
> > >
> > > public void getAlwaysFoo() {
> > >     if (foo == null) {
> > >         setFoo(Foo.newBuilder().build());
> > >     }
> > >     return foo;
> > > }
> > >
> > > This way the automatically created instance immediately has all the
> > > defaults I have defined.
> > >
> > > Assuming this naming my code will be readable because it will look like
> > > this:
> > > public void setSomething(String value) {
> > >     myStruct
> > >             .getAlwaysFoo()
> > >             .getAlwaysBar()
> > >             .getAlwaysOne()
> > >             .getAlwaysOther()
> > >             .setSomething(value);
> > > }
> > >
> > > I can create this same effect in my own project code.
> > > But having this automatically generated by the Avro engine would make
> > life
> > > a lot easier.
> > >
> > > Is this an idea you guys would consider to have in the main (Java)
> > > generated code base?
> > > If so, is the 'getAlways' prefix sensible?
> > >
> > > --
> > > Best regards
> > >
> > > Niels Basjes
> > >
> >
> >
> >
> > --
> > Best regards / Met vriendelijke groeten,
> >
> > Niels Basjes
> >
>



-- 
Best regards / Met vriendelijke groeten,

Niels Basjes

Re: Always getting a value...

Posted by Sean Busbey <bu...@cloudera.com>.
What does an example schema look like in this case?

Shouldn't the extant builders give you this behavior if you've made the
default for the optional fields non-null?

-- 
Sean
On Nov 26, 2014 11:34 AM, "Niels Basjes" <Ni...@basjes.nl> wrote:

> Oops,
> That should be
>      public Foo getFoo()
> and
>      public Foo getAlwaysFoo()
> ofcourse
>
> On Wed, Nov 26, 2014 at 6:28 PM, Niels Basjes <Ni...@basjes.nl> wrote:
>
> > Hi,
> >
> > I have a Java project where I'm using Avro as the serialization
> technology.
> > I have a deep nested structure and many fields are optional.
> >
> > Because of the 'random' nature of my application I want to be able to
> > simply 'set' a value in that tree easily.
> >
> > So I want to have a setter in my class that looks like this (Assume
> > myStruct is an instance of the 'root' class generated by Avro):
> >
> > public void setSomething(String value) {
> >     myStruct
> >             .getFoo()
> >             .getBar()
> >             .getOne()
> >             .getOther()
> >             .setSomething(value);
> > }
> >
> > The 'problem' I ran into is that any of the 4 get methods can return a
> > null value so the code I have to write is really huge.
> > For every step in this method I have to build null checks and create the
> > underlying instance if it is null.
> > I already started writing helper methods to do this for parts of my tree.
> >
> > To solve this in a way that makes this code readable I came up with the
> > following which I want to propose to you guys (before I start working on
> a
> > patch).
> >
> > My idea is to generate a new 'get' method in addition to the existing
> > normal get method for the regular instance of the class.
> >
> > So in addition to the
> >
> > public void getFoo() {
> >     return foo;
> > }
> >
> > I propose to generate something like this as well
> >
> > public void getAlwaysFoo() {
> >     if (foo == null) {
> >         setFoo(Foo.newBuilder().build());
> >     }
> >     return foo;
> > }
> >
> > This way the automatically created instance immediately has all the
> > defaults I have defined.
> >
> > Assuming this naming my code will be readable because it will look like
> > this:
> > public void setSomething(String value) {
> >     myStruct
> >             .getAlwaysFoo()
> >             .getAlwaysBar()
> >             .getAlwaysOne()
> >             .getAlwaysOther()
> >             .setSomething(value);
> > }
> >
> > I can create this same effect in my own project code.
> > But having this automatically generated by the Avro engine would make
> life
> > a lot easier.
> >
> > Is this an idea you guys would consider to have in the main (Java)
> > generated code base?
> > If so, is the 'getAlways' prefix sensible?
> >
> > --
> > Best regards
> >
> > Niels Basjes
> >
>
>
>
> --
> Best regards / Met vriendelijke groeten,
>
> Niels Basjes
>

Re: Always getting a value...

Posted by Niels Basjes <Ni...@basjes.nl>.
Oops,
That should be
     public Foo getFoo()
and
     public Foo getAlwaysFoo()
ofcourse

On Wed, Nov 26, 2014 at 6:28 PM, Niels Basjes <Ni...@basjes.nl> wrote:

> Hi,
>
> I have a Java project where I'm using Avro as the serialization technology.
> I have a deep nested structure and many fields are optional.
>
> Because of the 'random' nature of my application I want to be able to
> simply 'set' a value in that tree easily.
>
> So I want to have a setter in my class that looks like this (Assume
> myStruct is an instance of the 'root' class generated by Avro):
>
> public void setSomething(String value) {
>     myStruct
>             .getFoo()
>             .getBar()
>             .getOne()
>             .getOther()
>             .setSomething(value);
> }
>
> The 'problem' I ran into is that any of the 4 get methods can return a
> null value so the code I have to write is really huge.
> For every step in this method I have to build null checks and create the
> underlying instance if it is null.
> I already started writing helper methods to do this for parts of my tree.
>
> To solve this in a way that makes this code readable I came up with the
> following which I want to propose to you guys (before I start working on a
> patch).
>
> My idea is to generate a new 'get' method in addition to the existing
> normal get method for the regular instance of the class.
>
> So in addition to the
>
> public void getFoo() {
>     return foo;
> }
>
> I propose to generate something like this as well
>
> public void getAlwaysFoo() {
>     if (foo == null) {
>         setFoo(Foo.newBuilder().build());
>     }
>     return foo;
> }
>
> This way the automatically created instance immediately has all the
> defaults I have defined.
>
> Assuming this naming my code will be readable because it will look like
> this:
> public void setSomething(String value) {
>     myStruct
>             .getAlwaysFoo()
>             .getAlwaysBar()
>             .getAlwaysOne()
>             .getAlwaysOther()
>             .setSomething(value);
> }
>
> I can create this same effect in my own project code.
> But having this automatically generated by the Avro engine would make life
> a lot easier.
>
> Is this an idea you guys would consider to have in the main (Java)
> generated code base?
> If so, is the 'getAlways' prefix sensible?
>
> --
> Best regards
>
> Niels Basjes
>



-- 
Best regards / Met vriendelijke groeten,

Niels Basjes