سؤال

I'm sorry to bother you with this question but I end up finding a head stomper, and I am wondering if I'm dealing with this the wrong way.

I want to map a class containing a collection of org.springframework.security.core.authority.SimpleGrantedAuthority so that I don't need to send it eagerly loaded by the ORM, into the spring security classes. But its "role" attribute is associated with the getter "getAuthority", and that is when Orika means trouble. Can I force Orika to use the values returned by a getter, to put it into a setter of the destination class?

If you care enough, here's a little context ot my problem. I'm using Spring security for an app. I have a service which returns a org.springframework.security.core.userdetails.UserDetails so that spring can check if the user is authenticated and it has permissions. The implementation of UserDetail we have is a local one named User. Since this class implements org.springframework.security.core.userdetails.UserDetails, it has the method public Collection<? extends GrantedAuthority> getAuthorities(); which returns the permissions for this user.

Everithing was well, except for the fact that we had this User in the database, handled with hibernate. The first choices where to leave an open session in view. We don't want that. The second choice was to make the fetching of the ORM, EARGER. We didn't want that either. So, we decided to use a DTO, implementing UserDetail, and map it with orika. That's when all hell broke loose. org.springframework.security.core.GrantedAuthority is an interface. The concrete class we are using is org.springframework.security.core.authority.SimpleGrantedAuthority. And this is an obscure and deadly class to map, because it has an attribute name "role", but its getter is "getAuthority"

public String getAuthority() {
    return role;
}

It appears that the Spring team and the Orika team where not very close friends. Otherwise they would've name the property, according to the java standard, and orika would've mapped it straight forward. I am, also, reluctant to define a custom mapper for this particular case, and that's what's been bothering me. Is there any known way of forcing Orika to use the value returned by the getter method other than replacing all its 'magic' with a custom mapper for a particular class?

هل كانت مفيدة؟

المحلول

Well, in the end, it pays to be stubborn as I am :)

I fixed the issue in question without having to appeal to any trick. The problem that was interfering with my mapping was the generic on the collection returned by the getter. You'll see, it seems that orika can't handle the following mapping... at least, I didn't know.

public List<? extends GrantedAuthority> getAuthorities() {
    return this.role;
}

I changed it into

public List<GrantedAuthority> getAuthorities() {
    return this.role;
}

and worked just fine!

Thanks a lot for the time and attention!

نصائح أخرى

We have roles (which extend GrantedAuthority) setup like this in our user object:

private Set<Role> roles = new HashSet<Role>();

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE})
public Collection<? extends GrantedAuthority> getAuthorities() {
    return roles;
}

Note it's lazily loaded, but switching to eager fetch shouldn't cause problems:

private Set<Role> roles = new HashSet<Role>();

@ManyToMany(cascade = {CascadeType.PERSIST, CascadeType.MERGE}, fetch=FetchType.EAGER)
public Collection<? extends GrantedAuthority> getAuthorities() {
    return roles;
}

I'm not too familiar with Orika, but in glancing at its docs, it seems you could just extend GrantedAuthority quite trivially with a Hibernate-enabled entity that would be straightforward for Orika.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top