-
-
Notifications
You must be signed in to change notification settings - Fork 2.4k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Generate hasXXX() method #2669
Comments
I like this feature request because it gives falsifiable context about adoption of this concept: mapstruct and protobuf appear to use this. It would have been even better if you link to the relevant sections. I can't find it for mapstruct, but here is java's protobuf implementation's hasMethod feature. What's less clear to me is what we want with this. A full technical outlay: Show me the code with lombok, and what it boils down to without. I can see a few routes, but I'm not a frequent user of these frameworks so I'll wait for proposals. Without them this isn't detailed enough to judge. |
This is my mistake, I am not focusing on the link to the mapstruct documentation, this is section Source presence checking. Here describing example: @Data
public class SomeEntity {
private Long id;
private String data;
}
@Data
public class SomeDto {
private Long id;
private String data;
public boolean hasId() {
return id != null;
}
public boolean hasData() {
return data != null;
}
} Mapper interface and implementation: @Mapper
public interface SomeMapper {
void toEntity(@MappingTarget SomeEntity entity, SomeDto dto);
SomeDto toDto(SomeEntity someEntity);
}
public class SomeMapperImpl implements SomeMapper {
@Override
public void toEntity(SomeEntity someEntity, SomeDto dto) {
if ( dto == null ) {
return;
}
// using hasField methods
if ( dto.hasId() ) {
someEntity.setId( dto.getId() );
}
if ( dto.hasData() ) {
someEntity.setData( dto.getData() );
}
return someEntity;
}
@Override
public SomeDto toDto(SomeEntity someEntity) {
if ( someEntity == null ) {
return null;
}
SomeDto someDto = new SomeDto();
// no hasField methods
someDto.setId( someEntity.getId() );
someDto.setData( someEntity.getData() );
return someDto;
}
} My feature suggestion: @Has
@Setter
@Getter
@NoArgsConstructor
@AllArgsConstructor
class Sample {
private String data;
}
// generated
class Sample {
private String data;
@Transient
private boolean __hasData = false;
public Sample() {} // __hasData = false
public Sample(String data) {
this.data = data; // or call setter
this.__hasData = true;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
this.__hasData = true;
}
@Transient
public boolean hasData() {
return __hasData;
}
}
@Has
@Setter
@Getter
@Builder
@AllArgsConstructor
@NoArgsConstructor
class Sample {
private String data;
}
// generated
class Sample {
private String data;
@Transient
private boolean __hasData = false;
public Sample() {} // __hasData = false
public Sample(String data) {
this.data = data; // or call setter
this.__hasData = true;
}
//private for builder only
private Sample(String data, boolean __hasData) {
this.data = data;
this.__hasData = __hasData;
}
public String getData() {
return data;
}
public void setData(String data) {
this.data = data;
this.__hasData = true;
}
@Transient
public boolean hasData() {
return __hasData;
}
class SampleBuilder {
private String data;
private boolean __hasData = false;
public SampleBuilder data(String data) {
this.data = data;
this.__hasData = true;
return this;
}
public Sample build() {
return new Sample(data, __hasData);
}
}
// .. builder() method
} As we can see - the idea is to mark the field as "touched" |
Use case for this feature request: {
"data": "123123"
} Logic: public void update(SomeDto dto, Long id) {
SomeEntity entity = repository.find(id);
someMapper.toEntity(entity, dto);
repository.save(entity);
} |
Let's forget, for a moment, about mapstruct and the like. Just look at the feature request. It's completely mystifying and makes no sense whatsoever. The fact that the There is no way to sanely document any of this whatsoever. Unless, of course, you say: Actually, this feature makes no sense unless you realize it's about making JPA/mapstruct/protobuf work (and I'm pretty sure all 3 really want entirely different things, they just all so happen to share one small aspect of it all, which is a method named hasX), and then document in terms of that. Which means as written this feature cannot be implemented (lack of sense). But there is an avenue to make e.g. the annotation This then also solves the problem that the proposed implementation doesn't seem like it's what you'd want for e.g. protobuf. The downside is, all lombok feature requests are judged based on 'value for the money'. This modification moves this feature request in the wrong direction on both fronts: The value goes down because it's just for one of the 3 targeted libraries instead of for all of them, and the cost goes up because we're now much more beholden to idiomatic JPA which is likely to change (that's the downside of speccing a feature in terms of 'it does thing X which is handy when using library Y: You're now beholden to the whims of Y'. With that in mind I doubt this will end up being a good idea, but, maybe. Focussing on just this JPA thing (which, at this point, has nothing whatsoever to do with mapstruct anymore, right, or do I misunderstand your example?) Looking specifically at your proposal for this feature: If builder is involved, that explodes the complexity (builder is already very complicated, piling on even more, that's possible but tricky). The proposal also interacts with Now if Builder in general seems lost here: Builder is primarily for immutables. This is not immutable, so, just.. call setters. That's what they're for. Forget builder, this feature proposal is DOA if that's involved. What if we just say that Even then this is more complicated than I had hoped. |
I like the idea but I'm unsure how it is related to JPA. Looks like it's more related to deserialization of data into objects. Useful for merge- With that in mind I don't see how this feature is related to any concrete framework/library. The only thing that a library must do is to use setters. And The manual code to implement common HTTP PATCH request could look like this: Order order = orderRepository.findOrder(orderId);
if (orderDto.hasName()) {
orderService.updateOrderName(order, orderDto.getName());
}
if (orderDto.hasApproved()) {
if (orderDto.isApproved()) {
orderService.approveOrder(order);
} else {
orderService.withdrawOrderApproval(order);
}
} This example shows code that support JSON MERGE PATCH requests with just 2 possible fields: To me, the main point of this feature request is to make Lombok to generate boilerplate that allows to check if some field was set at least once or never been set at all. The challenge here is to make generated boolean |
Okay, then what is that |
That means Maybe my grasp of english is weird, but how you get from "hasFoo" to "Foo has been changed" is based on wishes and voodoo magic only. Hence why this doesn't make sense unless you sign on to the fact that JPA and such came up with this turd. |
Here is a completely different take on with lombok:
delomboked:
Why doesn't it generate that? I find it hard to explain why not without saying something like: "Well, because the point of And if that's the goal, and we don't tie it to a framework, 'has', as an english word, doesn't suggest 'change management' whatsoever. I can see That is the dilemma here: Without tying it to a specific framework, it's either too hard to explain without mentioning those frameworks, or it's useless. |
What do you mean "mine" snippet? I'm not the author of this issue. In my code there is no
I'm not a native English speaker. Maybe that is why I don't see a big problem here. To me it sounds good. Not "Foo has been changed" though, but rather "Foo has been set (at least once) and now the object has this property (set) as opposed to a previous state when this property was never set and this object hadn't this property then". But I agree it is somewhat contrived. It's not me who offered this For example, in the link you mentioned earlier I found this:
So, the semantic is basically the same I have in mind. I think the logic here is the same as with
I still don't see how does this relate to JPA. If you give me an example it would be good. Also, your delomboked example makes no sense to me. Why But, I'll repeat - I am not the original author of this request and maybe my vision is very different from author's. I just wanted to add my 5 cents to maybe let others a broader vision to this request than associate it with some concrete library.
Sorry, I'm not sure who you are talking to. If to the author of the issue (@lex-em), then I agree (he wants it for concrete library What does matter to me is to have some way to mark generated boolean fields as ignorable for Jackson (yes, my primary use-case is bound to a library too :) ). But I think it's possible with some configuration of objectmapper (e.g. configure it to use only getters and ignore all fields altogether or generate inner class as a wrapper for boolean properties and then manually put |
I meant lex-em's snippet.
But lex-em's snippet doesn't do this, and you haven't proposed anything yet, just showed some nebulous usage. Perhaps you have a different idea about what this feature ought to do than lex-em. Can you post a 'with lombok' and a 'this is what lombok would delombok it to' example side-by-side so I can follow along with what you're thinking about?
Lex-em's proposal, as linked above.
That's another use case: There is:
I'm pretty sure that 5th case is a few orders of magnitude too rare to be called boiler-plate though. This feature stands very little chance unless it picks up enough ground to qualify as boilerplate, so I'm pretty sure it needs to cover all or most of that list. My prediction that these are 5 separate feature requests that are mostly unrelated, except they share the name 'hasX', seems to be coming true, and if true, that's... not helping this proposal at all; confusion increases the 'cost' factor in the 'value/cost' calculation considerably. |
Actually his example does it, but only for
Of course! @Data @AllArgsConstructor
class Example {
@Has String foo;
} Delomboked: class Example {
private String foo;
private boolean __hasFoo; // or maybe wrapped in inner class
// all the normal stuff, unchanged; equals, hashCode, etc.
// all args constructor too. Unchanged from current lombok. and also:
public void setFoo(String foo) {
this.foo = foo;
this.__hasFoo = true; // setter must update the corresponding boolean field
}
public boolean hasFoo() {
return this.__hasFoo; // true only if setter was called at least once, even it `null` was it's argument
}
} Basically this is the same as To me it could be usable for implementing PATCH-requests in REST API. If DTO class has 50 fields it's pretty large boilerplate to add all these boolean But let's listen what @lex-em think about it. Maybe I turned the discussion in the wrong way and my "feature request" is actually not directly related. :) |
I'm not sure I follow your example, so let me check first: If lombok worked as your delomboked example shows, then this is what would happen:
Is that really what's supposed to happen here? If true, I'm vetoing the request (specifically, the 'the feature stands on its own, and not in relationship to any specific java framework/library') - It makes zero sense that
If the above 4 prints is not what's supposed to happen, can you correct the delomboked example / post a new take? |
I have no worthwhile input on the various frameworks, but at my company, we too follow the idiom of having 'has'-methods to simply provide a DSL of sorts around null/0 checks (we also have them for I would love to see this as a basic feature because I feel that the readability is much nicer, but I understand that we too may be an edge case. |
@rzwitserloot what about serialization - temporary fields @xak2000 says and I totally agree
@rzwitserloot It is wrong, because the point is that "does
@xak2000 I agree, but it is not competable with other libraries
Yes, that's right
@rzwitserloot why? The part with generated code for proposal does exactly that, setting
No, I meant only mapstruct part. Other libraries only for sample |
Yes, that right
No, that is wrong, because |
No, this is quite useful! It suggests my idea that a method named |
Before we go any further on this, I still have absolutely no idea why this boolean is needed. I'm trying to fully grok what you're trying to do. Forget lombok, forget technical descriptions, what is your API supposed to do? So far, I've gathered conflicting information. Something about protobuf, something about mapstruct. From what I was able to gather from those, the point of it all is for mapstruct and protobuf to know what needs updating when sending/persisting/converting explicitly vs. what needs to be not sent/not named in the sql UPDATE statement/not converted, thus relying on the default in the target. Which is a fine feature, but the name If I understand what you want correctly, you want this behaviour. Given
*1) You say you wanted the boolean fields to be transient. Then this nuttiness is what would ensue. I can see the point if the idea is 'track changes', but the name *2) Given that you want booleans, this bizarre answer (a person with null for a name 'has a name') is evidently what you'd want, or, if not, what am I missing?
If it is possible to determine the state of those boolean fields based solely on the other fields, then why the heck are these fields in the first place? Why bother storing information that can be cheaply derived at all?
Okay, so you want this:
In other words, differentiate between 'the value is null, and that is because nobody set it yet' and 'the value is null, and that is because somebody explicitly set it to that value'. Why do you want that? That's what I need to understand. It sounds like rather exotic bit of terrible code design to care about this (heck, in other threads I'm fighting the good fight about folks who want to eliminate |
@rzwitserloot I'll try to describe my use-case. But I should warn you that it could be not the same as lex-em's. But 2 use-cases are better than one, right? :) Let's imagine, I want to implement a REST API to manage marketplace For simplicity my update request will have 2 fields. In real app it would be much more. @Data
class UpdateOrderRequestDto {
private String shipmentAddressId;
private Boolean active;
} It's very important to understand, that this class will be used exclusively as a container to deserialized representation of JSON body of HTTP requests! So if I would call Now, I want my users to be able to send any combination of fields in JSON body of HTTP requests. Update shipment address and deactivate the order: {
"shipmentAddressId": "XXX",
"active": false
} Update shipment address: {
"shipmentAddressId": "YYY",
} Activate the order: {
"active": true
} All these requests are valid. It's also important for this API to support removing of {
"shipmentAddressId": null,
} and server must then remove a shipment address from this order, if it's currently set and order is not complete yet. Now, in my business logic I want to check what fields were really present and what were not. I need this because of mentioned early requirement. I can't just check for Currently there is a way to achieve what I described using So, that's why I liked this idea of
It's hard to say. At first I want to say "no". Because constructor also must use setter and so So, answering your question - looks like it doesn't matter for my use-case. My class must be constructed using default constructor only and it must not have any other costructors. |
More thoughts. If the same class Currently I don't know if, say, Jackson could be configured to do this. By the way, for request side it would be good to have another set of |
You nailed it. That's the problem. I'll take credit for my haphazard floundering in an attempt to figure out how this is useful: My The problem is, we have the following issues now, assuming we want your JSON use-case to work out, and we want this 'the booleans arent persisted, so upon loading from persistence, always init to false' thing from @lex-em:
Your second use case of having java be on the other side and send a cutdown JSON dump listing only the changed fields also seems to match exactly with wanting the notion of 'hasXChanged', running headfirst into the giant bar of 'why the heck is the standardized name for this method This is heading rapidly to the unfortunate conclusion of: Because the authors of jackson and protobuf screwed up, lombok must sign on to the same mess, and that's severely hampering the chances of this proposal. Unfortunately, I highly doubt jackson and protobuf are willing to acknowledge they done goofed on the naming, let alone fix it. If somehow these parties are on board for a name change, I'm game. Proposed annotation name: |
This change detection mechanism seems to be similar to @BoundSetter. Wouldn't it be more useful to implement it like this: Before @Data
class Example {
@TrackChanges String foo;
} After class Example {
String foo;
private PropertyChangeSupport propertySupport = new PropertyChangeSupport(this);
{
addPropertyChangeListener(new PropertyChangeListener() {
void propertyChange(PropertyChangeEvent evt) {
changed.put(evt.getPropertyName(), true);
}
})
}
private Map<String, Boolean> $changed = new HashMap<>();
public void addPropertyChangeListener(PropertyChangeListener listener) {
this.propertySupport.addPropertyChangeListener(listener);
}
public void removePropertyChangeListener(PropertyChangeListener listener) {
this.propertySupport.removePropertyChangeListener(listener);
}
public void setFoo(String foo) {
String old = foo;
this.foo = foo;
this.propertySupport.firePropertyChange("foo", old, foo);
}
public boolean hasFoo() {
return this.$changed.get("foo");
}
} |
@Rawi01 Going back to the underlying problem that this feature is ostensibly trying to solve: If generating all that jazz will magically make protobuf and mapstruct just do the right thing, maybe. However, your proposal doesn't solve one of the dilemmas that I really, really want solved first: It makes a method named |
I agree with you that the name is misleading in general but it doesn't feel that wrong if you are in a deserialization context. It seems like that protobouf already generates these fields for a About my proposal: I would expect to get code that enables object change tracking using something like a listener if I use |
I'll repeat myself:
If you look to Proposition: can the new annotation have Like this:
|
@Rawi01 wrote:
That is an excellent point. |
@xak2000 wrote:
Sure. It's not about what you need. It's about what one would expect a method named
I see now. I think I'm too unfamiliar with the problem domain (or I'm having a dumb moment) as I didn't really get it first time I read this, but I think I do now. I'm not sure that mental model actually 'works'. If I understand you correctly, you have a domain model, let's say it represents a Course at a university. The Course itself has the property of 'title'. And what you're suggesting is that e.g. Therefore, Did I get that right? However, if that's the actual mental model, then Returning the title of the underlying domain object (Course itself) if you call
I'm not sure it solves much. If the default is |
I fully agree with @xak2000 in message #2669 (comment) It is mostly json deserialization feature for partial changes (patching), my example with the builder could be superfluous at this stage, but in the future it would be nice to have such functionality in view of the fact that we can make such requests from Java code (it builds with builders for some reasons, but not necessary). there we can still tweak the serialization and send only the necessary (through Let's forget about builders for now, understanding of how to do better may come later. @rzwitserloot can I ask a question? why you are catch on jpa? may be I was incorrect, but I didn't meant to use it with jpa, only DTOs from json
why it should return
@rzwitserloot okay, I see you are picking on the name |
i see it was already proposed)))
|
@rzwitserloot what is my initial point: any data format (json, xml, any other) have three states:
unfortunately java does not present the first state, unlike javascript for example. we will newer know does input data have value and if it have null - we need to handle it as set null. this featire intended to solve this situation. how it cleary can be solve? I think just generate setting |
transient, in most contexts (or, at least, the context of both JPA and serialization), means that it doesn't survive persistence or transfer and will revert to a default value and/or is reconstructed based on the other fields. So, going back all the way to the first few posts in this issue: Can we consider the mention of |
we are only looking over deserialization from three-state sources with partial structure (json from HTTP PATCH), we do not looking over persisting via jpa or other orm, or serializing. in that cases no three states in data and there no need to this feature. serializing and persisting of boolean flags are not necessary at all
Are you looked at my last propersal #2669 (comment)? @Has(suffix="", onMethod=@__(@JsonIgnore)) // default prefix="has", suffix="Changed" |
@lex-em yes; as @filiphr from mapstruct mentioned, mapstruct is not the best fit for this, and they're also just giving in to established naming conventions - in their case, inspired by protobuf. That Transient thing is still a mystery to me. What happened to it? Your proposal no longer includes them, but your original request did, and I still have no idea what you're trying to accomplish with that |
@rzwitserloot Looks like |
@rzwitserloot Forget about
No, the class that represents JSON request must have getters because request can be seen from two sides:
Both sides working with request. The side that sends it doesn't require getters. But the side receiving it requires them to get the data from this request, obviously. Unlike builder, that is used only as temporal intermediate storage.
Yes, and most important here is that it's
No,
But you are talking about 2 different classes. You are talking here about
The transient nature of these In contrary, SQL doesn't! In SQL there are columns and if you set any value to a column you can't then know if the value was set or not (when SELECT-ing the data). So, if by "serialization" you mean "saving to SQL DB", then I agree, I already compared the @lex-em, are you sure it would work? I think Jackson will ignore
@rzwitserloot I'll repeat that What lex-em did mean is that JPA could be used together with MapStruct mapper together with Jackson deserialization together with JSON PATCH request together with My if (orderDto.hasName()) {
orderService.updateOrderName(order, orderDto.getName());
} calls service method, that could do business logic of any complexity. It could be just What is similar in my example and MapStruct's generated mapper (or manually written mapper) is that they both need to know which fields were included in the received JSON. So, I agree that this feature request is indeed very tied to serialization/deserialization, but don't agree that it is tied to MapStruct or, especially, JPA. If you ask me to select one framework that is tied to this feature, I would say Jackson (or any other JSON-serialization framework). Even Protobuf is not related here, because it already implements Also, I agree with @almson about OOP. I like his I found an interesting example from Google Classroom API to update If we would try to implement this feature to support server-side of this API, it would be implemented exactly the same way as earlier described, but deserialization code must not call setters of So, this API uses totally different way of marking fields to "patch" (query parameter instead of excluding fields from JSON), but still fits well on this feature request. The only changing part is serialization/deserialization. |
@xak2000 yes, you are right - annotation is not needed on |
public @interface Has {
String prefix() default "has";
String suffix() default "Changed";
AnyAnnotation[] onMethod() default {};
AnyAnnotation[] onField() default {};
} |
@rzwitserloot what do you think about implementation? you will do this? |
I've had to go on a deletion spree due to some proseletyzing of optional, which is entirely inappropriate here. Optional is shot down for this, for extremely obvious reasons, and any comments that suggest it will be deleted. There are plenty of issues around where such discussion is begrudgingly allowed; this is not one of them. EDIT: I now see github has 'hide' functionality. That's fantastic, but I saw that too late. I'll use that next time, though. NB: To all except @randakar - your comments were fine, I just deleted them because they were in response to comments that I deleted. Your opinions are noted and agreed on :) |
We've spent a million comments on this. A lot more is clear, and yet, we are no further to a fully fleshed out proposal (@lex-em - your 'fully fleshed out proposal' is very far removed from what is needed! It doesn't explain how e.g. Let's lay down what we do know, and what it missing. Please double-check my work. Agreed on:
Open problems:
This is a bug - now your CCR is broken, because it should have written
into:
Where, presumably, jackson automatically gets it right because it realizes that the Holder would be something like:
Lombok cannot, however, contribute any types here, because lombok is not present at runtime, and there is no suitable Holder anywhere in the JDK, so that's quite a big issue that needs addressing first, then. In all the traffic I may have missed answers to some of my open issues, but without a really good answer to all of them I'm closing this one. Too complicated for not enough gain. |
I'll try to answer some of the questions, but not all.
This is actually not a problem. @lex-em is right, that Jackson by default will not serialize/deserialize any private fields. It could be configured to do it, but by default Jackson uses presence of getter as an indicator if field must be considered as a property (so, participate in ser/deser) of just be ignored. I tried it on this class: @ToString
@EqualsAndHashCode
private static class RequestWithPrivateField {
private String foo; // no getter/setter - will be serialized/deserialized? No.
@Getter @Setter
private String bar;
public RequestWithPrivateField() {
}
public RequestWithPrivateField(String bar) {
this.bar = bar;
}
} With this code: ObjectMapper objectMapper = new ObjectMapper();
String json = "{\"bar\": \"bar-value\"}";
RequestWithPrivateField request = objectMapper.readValue(json, RequestWithPrivateField.class);
String jsonSerialized = objectMapper.writeValueAsString(request);
log.info("Request deseriazlied from {} into {} and serialized back into {}", json, request, jsonSerialized); And the output is:
I don't think this feature is directly related to Mapstruct. Yes, mapstruct can use
For serialization stage, unfortunately, no. Jackson don't use On deserialization, Jackson just calls setters for any field, that is present in source JSON. This is fine. You can also configure it to use a builder, but this is not required. You raised a good questions. I don't have answers to all of them. :( I like you idea with |
Wow! Sweet. Yeah that definitely helps. That's one of my open issues eliminated.
Let's go back to the very first post - the original request:
What am I missing? These two statements seem like they contradict each other. I've also solved my own holder problem, sort of: We can do it! With an AtomicReference. Turn:
into:
We can use a lot of the code from We could, presumably, demand that the field is non-final, and have So, current open questions:
|
I'll try to answer some of the questions related to MapStruct and maybe chime in on some of the other points.
The place where it makes the most sense for users to use The users write something like:
The code that MapStruct generates looks like:
When
Basically extremely similar to what @xak2000 explained in #2669 (comment). Long story short, in my opinion there is nothing MapStruct specific needed in Lombok regarding the Regarding the 1.
|
That's what However, the maintenance burden for this would probably be very high, because of all these interactions with other features. |
I described serialization stage and behavior of Jackson (when you already have an object with @lex-em described deserialization stage and behavior of Jackson + Mapstruct (that operates with already deserialized data (java object)). So, this is the case, when you already have partially filled JSON and want to:
So, there is no contradiction here. They are 2 different use cases: serialization vs deserializtion. Deserialization case will be solved with presence of |
There is |
Regarding the Jackson deserialization stage, I would advise someone to open an issue in the Jackson tracker to support this kind of |
I think this will be a good new feature in jackson! But now we are considering a case of deserialization at first. @rzwitserloot I think enough to use what opened issues do we have now? |
Since my last comment this discussion seems to be heading back to the setup where
vs my idea of changing that to:
The problem with the first 2 is: Given that the field is left intact, the author of the code is likely going to write, for example, So, one major unanswered question now is remains: What should lombok actually do in the face of this Separate from that, given that interactions required with the already very complicated What is really working out right now, though, is the consensus on what this does and what it should be called: 'presence' (I'm even thinking the annotation might need to be |
No, I think we were all talking about the |
Recently I published to maven central lombok extension to do exactly what OP is talking about: lombok-presence-checker It does the following: // Original code
@PresenceChecker
@Getter
@Setter
public class UserUpdateDto {
private String name;
}
//Generated code
public class UserUpdateDto {
private boolean hasName;
private String name;
public String getName() {
return this.name;
}
public void setName(String name) {
this.name = name;
this.hasName = true;
}
public boolean hasName() {
return this.hasName;
}
} The annotation works on class and field levels. It works well with MapStruct. Check an example |
@kokorin Nice to have a PoC to play with, but what do you think about the problems I raised? For example, someone could write this code:
That code seems fine, but it is broken because it forgot to update the hidden |
@rzwitserloot Actually lombok-presence-checker doesn't generate a setter itself, but it requires a setter to be either generated with lombok, or to be written manually. During code generation it alternates a setter and adds The main use case for the extension is DTO partial update. Personally I don't want this extension to be included into core lombok. If anyone uses it he/she should understand that problems may appear. I posted a link to my project here only to point that it's not required to bother core lombok authors to support P.S. lombok-presence-checker is really an extension, not a fork. |
Hello!
Some frameworks have support of
hasXXX
methods, for example mapstruct: if fielddata
have additional methodboolean hasData()
then generated code will call this method and do check around setting target field value.Same facilities have protobuf.
Possible realization is create annotated with
@Transient
(json generation for example or jpa) methodhasData()
with backing transient boolean field__hasData
, set__hasData
totrue
(defaultfalse
) whendata
setter called, or fielddata
initialized via constructor (builder)The text was updated successfully, but these errors were encountered: