Search code examples
javamongodbspring-dataprojection

How can I use Spring Data Projection with a Transient property?


I'm using Spring Data with MongoDB and a projection interface for one of the repositories.
The issue is that a transient field on my entity is not recognized as a valid property on the model since it is not part of the query results. [assumption]

Is there a workaround for this?

Example -

// Entity class fields 
@JsonProperty(access=Access.WRITE_ONLY)
private String password;
@Id
private String username;
private String displayName;
@DBRef
private Set<EmailAddress> emailAddresses = new HashSet<>();
@DBRef
@NotEmpty
private EmailAddress primaryEmailAddress;
private boolean hidePrimaryEmailAddress;
private String firstName;
private String lastName;
@JsonTypeInfo(use = com.fasterxml.jackson.annotation.JsonTypeInfo.Id.NONE)
private Set<Role> authorities;
private boolean accountNonExpired;
private boolean accountNonLocked;
private boolean credentialsNonExpired;
private boolean enabled;
@Transient
private String gravatarUrl;

.....

// Spring Data Projection 
public interface ProfileProjection {
  @Value("#{target.primaryEmailAddress.emailAddress}")
  String getEmailAddress();
  String getUsername();
  String getDisplayName();
  String getGravatarUrl();
}  

// Repository
public interface UserRepository extends ExtendedMongoRepository<SproutUser, String> {
    ProfileProjection findFirstByUsername(String username);
}  

Exception -

No property gravatarUrl found on savantly.sprout.domain.SproutUser!

Solution

  • I used SPEL to call the getter rather than depending directly on the field.

    public interface ProfileProjection {
        @Value("#{target.primaryEmailAddress.emailAddress}")
        String getEmailAddress();
        String getPrimaryEmailAddress();
        String getUsername();
        String getDisplayName();
        @Value("#{target.getGravatarUrl()}")
        String getGravatarUrl();
    }