spring-projects / spring-data-commons

Spring Data Commons. Interfaces and code shared between the various datastore specific implementations.
https://spring.io/projects/spring-data
Apache License 2.0
778 stars 675 forks source link

Add support for Immutables #3157

Open requizm opened 1 month ago

requizm commented 1 month ago

Example:

// User.java
import org.immutables.value.Value;

@Value.Immutable
public interface User {
    @Value.Default
    default String getName() {
        return NameGenerator.random();
    }
}
// ImmutableUser.java
import org.immutables.value.Generated;

@Generated(from = "User", generator = "Immutables")
@SuppressWarnings({"all"})
@javax.annotation.processing.Generated("org.immutables.processor.ProxyProcessor")
public final class ImmutableUser implements User {
  private final String name;

  private ImmutableUser(ImmutableUser.Builder builder) { // What if we ignore this?
    this.name = builder.name != null
        ? builder.name
        : Objects.requireNonNull(User.super.getName(), "name");
  }

  private ImmutableUser(String name) { // Should use this
    this.name = name;
  }

  // ...

  @Generated(from = "User", generator = "Immutables")
  public static final class Builder {
    // ...
  }
}

In this code, it can't find constructor because there is a constructor that uses Builder as a parameter.

I don't want something big like creating constructor using Builder. If the class is auto-generated and the constructor parameter is builder, I want it to ignore it.

I could add @Value.Style(privateNoargConstructor = true) annotation to interface, so there would be noArg constructor but that's just workaround. It's not working with transiant types, etc. I prefer first solution if it's okay.

requizm commented 1 month ago

I'm aware that adding 3rd library to core library does not feel right, it should be done in the top layers. But I coudln't find the right place (except creating a custom converter). Somehow I need to change creator

mp911de commented 1 month ago

For an arrangement such as Immutables, typically, the entity refers to the interface. For Spring Data usage, you would need to divert all getPersistentEntity(…) calls to the actual implementation. Additionally, the generated code (as you've pointed out) doesn't meet Spring Data's conventions.

Immutables has a ton of annotations and built-in extensions. I wonder why there isn't a way for Immutables to generate @PersistenceCreator on the all-arg constructor.

For the time being, we do not see strong demand while having other items in our backlog that we see much more demand for.

requizm commented 1 month ago

@mp911de Thank you, I can close the issue according to your comment. But you added enhancement label. Will this be resolved in this repo? Or do we pass the ball to immutables and ask them to create a PersistenceCreator?

mp911de commented 1 month ago

We consider adding support for immutables an enhancement. We just don't have bandwidth to implement that.