Blazebit / blaze-persistence

Rich Criteria API for JPA providers
https://persistence.blazebit.com
Apache License 2.0
732 stars 87 forks source link

Bug in the AP for Implementations and the EV validation #1687

Open EugenMayer opened 1 year ago

EugenMayer commented 1 year ago

We are trying to implement DTOs as a based for EntityViews for different reasons

For this, we do the following

Entity

class AppleEntity {
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  private String name;
  private String type;
}

IdView

@Data
public interface AppleIdView {
    @IdMapper
    Long id;
}

Create / Update DTOs

@Data
public class AppleUpdateDTO implements AppleIdView {
    Long id;
    String name;
}
@Data
public class AppleCreateDTO extends AppleUpdateDTO{
    String type;    
}

Now our create/update views

@EntityView(AppleEntity.class)
@CreatableEntityView
abstract public class AppleCreateView extends AppleCreateDTO {
}
@EntityView(AppleEntity.class)
@UpdatableEntityView
abstract public class AppleUpdateView extends AppleUpdateDTO {
}

The Problem with the above would be, that the EVM scanner will now not detect the getter/setter at all or just the IdMapper annotation (we cannot tell)` - this is one bug / we expected to work. It should most probably not matter if the getter/setter are implemented or abstract (which AFAIU might be issue here).

To try to work around this issue we did

@EntityView(AppleEntity.class)
@CreatableEntityView
abstract public class AppleCreateView extends AppleCreateDTO {
    public AppleCreateView(
        @Mapping("id") Long id,
        @Mapping("name") String name,
        @Mapping("type") String type
    ) {
        super(id, name, type);
    }
}

The problem now is, that the AP that generates the AppleCreateViewImpl will fail to generate the constructor for the above. it will add the following constructor to the Impl

    public AppleCreateViewImple(
        Long id,
        Long id,
        String name,
        String type
    ) {
        ..
    }

I assume that the ID is always added as the default first parameter, no matter if it is already present. This means, the workaround cannot be compiled, while the one without Mapping will not validate.

We used the docs

EugenMayer commented 1 year ago

We should try to use @IdMapping and not @Mapping

@EntityView(AppleEntity.class)
@CreatableEntityView
abstract public class AppleCreateView extends AppleCreateDTO {
    public AppleCreateView(
        @IdMapping("id") Long id,
        @Mapping("name") String name,
        @Mapping("type") String type
    ) {
        super(id, name, type);
    }
}

to see if the *Impl is generated properly.