Skip to content
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

[BUG] @SuperBuilder(toBuilder = true) does not call ctor of the base class and does not call the @Builder.ObtainVia #3774

Open
BorisDaich opened this issue Nov 3, 2024 · 2 comments

Comments

@BorisDaich
Copy link

BorisDaich commented Nov 3, 2024

Describe the bug
see the following sample classes . as the result the inherited member of the base class is never initialized

To Reproduce

@SuperBuilder(toBuilder = true)
public abstract class AbstractPropertyChangeSupport implements Serializable {
	@Builder.ObtainVia(method = "createPCS")
	@JsonIgnore
	protected transient PropertyChangeSupport pcs = new PropertyChangeSupport(this);

	protected PropertyChangeSupport createPCS() {
		return new PropertyChangeSupport(this);
	}

	public AbstractPropertyChangeSupport() {
		pcs = new PropertyChangeSupport(this);
	}

	public AbstractPropertyChangeSupport(PropertyChangeSupport pcs) {
		super();
		if (pcs == null)
			pcs = new PropertyChangeSupport(this);
		this.pcs = pcs;
	};

	// this is for the Deserialization ...
	private void readObject(java.io.ObjectInputStream stream) throws IOException, ClassNotFoundException {
		stream.defaultReadObject();
		pcs = new PropertyChangeSupport(this);
	}

}
@SuperBuilder(toBuilder = true)
@Data
@ToString(callSuper = false)
@EqualsAndHashCode(callSuper = false)
@NoArgsConstructor
public class TestDerived extends AbstractPropertyChangeSupport {

	@Builder.Default
	protected String value = "Foo";

	public static void main(String[] args) {
		TestDerived x = TestDerived.builder().build();
		if (x.pcs == null)
			System.err.println("thie PCS is NULL");
		System.out.println(x);
	}

}

Expected behavior
at the point after
TestDerived x = TestDerived.builder().build();
x.pcs should not be null.

Version info (please complete the following information):

  • Lombok version 1.18.34
  • Platform Java 17 eclipse 2024-09 4.33.0

thank you for the great Tool!!!!

@janrieke
Copy link
Contributor

janrieke commented Nov 4, 2024

@SuperBuilder creates its own constructor, which takes a builder instance as its only argument. This constructor copies the values from the given builder to the new instance. However, as the builder has pcs == null, the new instance also receives that null value. So this behavior is expected.

I'm afraid there is no easy solution here. If you need a reference to the instance in construction, you cannot do set in the builder, because there is no such instance, yet. So neither @Builder.Default nor @Builder.ObtainVia plus toBuilder() will work (the latter will compile, but the resulting PropertyChangeSupport instance will have a reference to the old instance, not the new one).

You could manually implement the ctor, but that would take away most of the benefits of lombok in this case: You'd have to implement the copy mechanism by yourself. What you could use is @PostConstructor #1207, but that feature is not finished, yet.

@janrieke
Copy link
Contributor

janrieke commented Nov 4, 2024

PS: @Builder.Default could provide a way out at least for @SuperBuilder, because it is only called from the ctor, so the generated init method could also be non-static. However, I remember that we had a discussion about this and we decided to leave it static, but I do not recall the reason and cannot find the discussion here on GitHub.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants