1

I am using @RepositoryRestResource facility,but I would like to do a calculation (depending on external service) over a transient field each time the user executes a read operation GET, find etc..

If only there was an AfterGet/AfterFind event at list I could handle the modification by extending AbstractRepositoryEventListener

Any clean suggestion?

Whimusical
  • 6,401
  • 11
  • 62
  • 105
  • how about using AOP? – Akshay Khopkar Jul 16 '19 at 21:35
  • 1
    A `@PostLoad` entity listener would be a possible solution. Traditionally there was a bit of hacking involved to make an entity listener spring managed however there's an answer here suggesting this is now straightforward in recent versions of Spring/Hibernate. If not then other solutions exist. https://stackoverflow.com/a/55452014/1356423 – Alan Hay Jul 17 '19 at 07:13
  • Thanks! But I need to call an external service, I am not sure it makes sense to inject a dependency into the entity for @PostLoad neither in the stateless entitylistener – Whimusical Jul 17 '19 at 14:50
  • *I am not sure it makes sense to inject a dependency into the entity for @PostLoad neither in the stateless entitylistener*. Sorry, but what does this mean? Logic will be handled by entity listener external to your Entity rather than via a callback method defined within it e.g. http://www.thejavageek.com/2014/05/24/jpa-entitylisteners/ – Alan Hay Jul 17 '19 at 15:00
  • My calculation relies on an external call, where should I place this if entities and entitylisteners are meant to be stateless? – Whimusical Jul 17 '19 at 15:02
  • What do you mean by stateless in this context? – Alan Hay Jul 17 '19 at 15:03
  • `An entity listener is a stateless class with a no-arg constructor. An entity listener is defined by annotating the entity class with the @EntityListeners annotation`https://docs.jboss.org/hibernate/entitymanager/3.6/reference/en/html/listeners.html – Whimusical Jul 17 '19 at 15:13
  • I think I put it in bad words.. the code that does the call is in an external dependency, I must find a way to inject it to the EntityListener but it is not alllowed – Whimusical Jul 17 '19 at 15:25

1 Answers1

1

I found the way through @Alan Hay suggestion.

@Entity
@EntityListeners(TransientFieldResolver.class)
public class Entity {

    private Long id;
    private String transientField;
}

@Component
public static class TransientFieldResolver {

    private static ExternalService externalService;

    @Autowired
    public void setExternalService(ExternalService externalService) {
        TransientFieldResolver.externalService = externalService;
    }

    @PostLoad
    public void onPostLoad(final Entity entity) {
        if (Objects.isNull(entity.getTransientField())) {
            TransientFieldResolver.externalService.fillTransientField(entity);
        }
    }
}
Alan Hay
  • 22,665
  • 4
  • 56
  • 110
Whimusical
  • 6,401
  • 11
  • 62
  • 105
  • Ironically I have a project where accepts injected entitites without no-args constructor, but it is not consistent in all projects... or either a feature allowed recently – Whimusical Nov 19 '19 at 11:18