0

I'm going to use @InsertOnlyProperty with Spring Boot 2.7 as it will take time for us to migrate to Spring Boot 3.0! So I'm going to create my DataAccessStrategy based on the DefaultAccessStrategy and also override the SqlParametersFactory so that I can pass the RelationalPersistentProperty::isInsertOnly condition to the getParameterSource method, also overriding RelationalPersistentProperty by adding isInsertOnly. And is there a way to override RelationalPersistentProperty to add isInsertOnly property. Am I correct or is there a better solution than switching to Spring Boot 3.0 now. Thank you!

Khusayn
  • 37
  • 6

1 Answers1

0

Since @InsertOnlyProperty is only supported for the aggregate root (in Spring Boot 3.0), one approach could be to copy the data to a surrogate object and use a custom method to save it. It would look something like this:

public record MyAggRoot(@Id Long id, 
  /* @InsertOnlyProperty */ Instant createdAt, int otherField) {}

public interface MyAggRootRepository 
  extends Repository<MyAggRoot, Long>, MyAggRootRepositoryCustom { /* ... */ }

public interface MyAggRootRepositoryCustom {
  MyAggRoot save(MyAggRoot aggRoot);
}

@Component
public class MyAggRootRepositoryCustomImpl implements TaskRepositoryCustom {
  @Autowired 
  private final JdbcAggregateOperations jao;
  
  // Override table name which would otherwise be derived from the class name
  @Table("my_agg_root") 
  private record MyAggRootForUpdate(@Id Long id, int otherField) {}
 
  @Override
  public MyAggRoot save(MyAggRoot aggRoot) {
     // If this is a new instance, insert as-is
     if (aggRoot.id() == null) return jao.save(aggRoot);

     // Create a copy without the insert-only field
     var copy = new MyAggRootForUpdate(aggRoot.id(), aggRoot.otherField());
     jao.update(copy);
     return aggRoot;
  }
}

It is however a bit verbose so it would only be a reasonable solution if you only need it in a few places.

dlesl
  • 26
  • 3