google / auto

A collection of source code generators for Java.
Apache License 2.0
10.43k stars 1.2k forks source link

Proper usage for data access #360

Closed 6bangs closed 5 years ago

6bangs commented 8 years ago

AutoValue is great for working with complete representations of objects, but I don't want to operate on fully-hydrated objects for every operation. For example, I may want to load only a user's name and nothing else, or update only his location but leave the rest of the properties alone.

As far as I can tell, there are two options:

Of course, I can always just load the entire object, use toBuilder() and change one or two fields, then persist the new object, but that's really wasteful. What are people doing in practice to solve this problem?

jbgi commented 8 years ago

I use algebraic data types and lenses, together with an adt generator that support lazy constructors. It allows to perform immutable updates deep in the data graph, as easily as with mutable setters.

ProgrammerAnthony commented 8 years ago

the same problem with @6bangs ,which even makes me more confused is that ,when there is a javabean class to serialize from Gson data with so many fields in this class ! but we don't wanna to serialize all of the fields .any idea ?

6bangs commented 8 years ago

@jbgi: wow, that's really cool. Do you use these with AutoValue or instead of AutoValue?

jbgi commented 8 years ago

@6bangs: I think one can create lenses for autovalue classes using https://github.com/gabrielittner/auto-value-with or more verbosely via the builder. Personally, I now use derive4j instead of AutoValue whenever the project is on jdk8 and the team is not averse to functional programming.

6bangs commented 8 years ago

Ah, yep. That's what I was getting at with regard to using toBuilder() for changing one or two fields. But still, the assumption is that we're dealing with objects that represent the entire record (a person with email, first name, last name, etc all filled in). If I want to use the same object but only fill in one or two fields that I care about depending on the use case, every property has to be Optional otherwise the Builder will throw IllegalStateExceptions.

Semantically, I guess it makes sense that a property would have to be Optional if I may or may not be using it depending on the use case. But then it's impossible to tell whether a property's value is absent because it wasn't queried or because the value's actually missing (the user doesn't have an email, for example).

jbgi commented 8 years ago

@6bangs yeah, for that, the lazy constructors generated by derive4j are very useful. edit: I guess one should be able to generate similar constructors via an auto-value extension.

eamonnmcmanus commented 5 years ago

As @6bangs says, if you have an AutoValue class that represents a query result, you can make properties Optional to mean that they weren't requested in the query. If a property is already optional by its nature (a middle name, say), and if you need to distinguish between "you didn't ask for the middle name" and "you asked for the middle name but there isn't one" then I suppose you could use Optional<Optional<String>>, where middleName().isPresent() means "you asked for the middle name" and middleName().isPresent && middleName().get().isPresent() (or middleName().orElse(Optional.empty()).isPresent()) means "you asked for the middle name and there was one". It isn't very elegant but I don't see a way to extend AutoValue to address it better.