I have an entity with a transient field. When I want to create a new instance of the object I lose my transient information. The following example demonstrates the issue.
Based on @Prassed Amazing answer I've created a more generic code:
I need to allow some transient fields on the entity (I mean fields that we do not keep on the DB, but we allow the user to fill them with data that we send to the server [with @JsonSerialize/@JsonDeserialize] and upload to file storage).
These fields will be annotated with the below annotation (RetentionPolicy.RUNTIME is used here so I can use reflection on those fields at runtime):
@Retention(RetentionPolicy.RUNTIME)
public @interface PreservePostMerge { }
Then, I traverse those fields using apache's FieldUtil:
@Aspect
@Component
public class PreservePostMergeData {
private final Logger log = LoggerFactory.getLogger(PreservePostMergeData.class);
@Around("execution(public !void javax.persistence.EntityManager.merge(..))")
private Object preserveTransientDataPostMerge(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
Object afterMerge = joinPoint.proceed();
if (args.length > 0) {
Object beforeMerge = args[0];
Field[] annotatedFieldsToPreserve = FieldUtils.getFieldsWithAnnotation(beforeMerge.getClass(), PreservePostMerge.class);
Arrays.stream(annotatedFieldsToPreserve).forEach(field -> {
try {
FieldUtils.writeField(field, afterMerge, FieldUtils.readField(field, beforeMerge, true), true);
} catch (IllegalAccessException exception) {
log.warn("Illegal accesss to field: {}, of entity: {}. Data was not preserved.", field.getName(), beforeMerge.getClass());
}
});
}
return afterMerge;
}
}