import java.util.HashSet;
import java.util.Set;

import lombok.Getter;
import lombok.Setter;
import lombok.ToString;
import lombok.EqualsAndHashCode;

@Getter
@ToString
@EqualsAndHashCode(onlyExplicitlyIncluded = true)
public class EqualsAndHashCodeDemo_WithNaturalId {
	@Setter
	private Long id;

	/**
	 * This is pseudo-final (not final, but not setters or other mutations) as a demo of how to handle this.
	 * It's required this way by some librariies/frameworks/environments, e.g. JPA
	 */
	@EqualsAndHashCode.Include
	private String naturalUniqueIdentifier;
	
	public EqualsAndHashCodeDemo_WithNaturalId(String naturalUniqueIdentifier) {
		this.naturalUniqueIdentifier = naturalUniqueIdentifier;
	}

	public static void main(String[] args) {
		EqualsAndHashCodeDemo_WithNaturalId demo = new EqualsAndHashCodeDemo_WithNaturalId("Some uniq String");
		Set<EqualsAndHashCodeDemo_WithNaturalId> set = new HashSet<>();

		if (set.contains(demo)) {
			throw new RuntimeException("We shouldn't end here since the demo is not in the set, yet");
		}

		set.add(demo);
		if (!set.contains(demo)) {
			throw new RuntimeException("We shouldn't end here either because the demo is in the set, now");
		}

		demo.setId(123L);
		if (!set.contains(demo)) {
			throw new RuntimeException("We shouldn't end here because hashCode has NOT changed");
		}
	}
}