I have an entity which looks like:
@Audited
@Data
@MappedSuperclass
@EntityListeners(AuditingEntityListener.class)
public abstract class BaseEntity {
public static final long UNSAVED = 0;
@Id
@GeneratedValue
private long id;
@CreatedDate
@Column(name = "created_at", updatable = false)
private ZonedDateTime createdAt;
@CreatedBy
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "created_by")
private User createdBy;
@LastModifiedDate
private ZonedDateTime updatedAt;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "updated_by")
@LastModifiedBy
private User updatedBy;
}
I'm want @LastModifiedBy and @CreatedBy so that they set corresponding users. However, when I try to save the entity, I get an exception:
java.lang.ClassCastException: Cannot cast java.lang.Long to com.intranet.users.Users
So it seems to me that it tries to set not actual User, but it's id. Is there any way to make spring set actual User on the entity and not just it's id?
Thanks
This seems to be answered pretty directly by the documentation:
In case you use either @CreatedBy or @LastModifiedBy, the auditing infrastructure somehow needs to become aware of the current principal. To do so, we provide an AuditorAware SPI interface that you have to implement to tell the infrastructure who the current user or system interacting with the application is. The generic type T defines what type the properties annotated with @CreatedBy or @LastModifiedBy have to be.
The following example shows an implementation of the interface that uses Spring Security’s Authentication object:
Example 104. Implementation of AuditorAware based on Spring Security
class SpringSecurityAuditorAware implements AuditorAware<User> { public Optional<User> getCurrentAuditor() { return Optional.ofNullable(SecurityContextHolder.getContext()) .map(SecurityContext::getAuthentication) .filter(Authentication::isAuthenticated) .map(Authentication::getPrincipal) .map(User.class::cast); } }
The implementation accesses the Authentication object provided by Spring Security and looks up the custom UserDetails instance that you have created in your UserDetailsService implementation. We assume here that you are exposing the domain user through the UserDetails implementation but that, based on the Authentication found, you could also look it up from anywhere.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With