simbro
simbro

Reputation: 3692

Spring Boot - Access JPA entity properties in controller method

I am having difficulty accessing the data of an instance JPA entity in my Spring Boot controller.

These are the entities:

User:

@Entity
@Data
public class User {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @NotNull
    @Column(unique=true, length=50)
    private String username;

    @OneToMany(cascade = CascadeType.ALL)
    private List<Authority> authorities = new ArrayList<>();
}

Authority:

@Entity
@Data
public class Authority {
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    private Long id;

    @NotNull
    private String authority;
}

UserRepository:

public interface UserRepository extends CrudRepository<User, Long> {
    Optional<User> findByUsername(String username);
}

This is the controller method:

@RestController
public class InfoController {
    @RequestMapping(value="/userinfo", method= RequestMethod.GET)
    public Optional<User> getUser() {
        Optional<User> foundUser = repository.findByUsername("testuser");

        return foundUser;
    }
}

When I access /userinfo in my browser I get this:

{
    "id": 1,
    "username": "testuser",
    "password": "",
    "enabled": true,
    "authorities": [
        {
            "id": 1,
            "authority": "ADMIN"
        }
    ]
}

So that's ok, looking good so far, but what I want to do is iterate over the authorities property of the User object in the controller, but I can't seem to access it (or any other property). I've tried using methods such as:

foundUser.getAuthorities();

foundUser.authorities;

foundUser.get('authorities');

....But none of those methods exist. How do I go about it?

Upvotes: 1

Views: 1791

Answers (2)

Jesper
Jesper

Reputation: 206996

Note that foundUser is an Optional<User> and not a User, so you cannot call methods of class User on it.

You'll have to get the User out of the Optional in order to access its attributes:

if (foundUser.isPresent()) {
    User user = foundUser.get();
    List<Authority> authorities = user.getAuthorities();
    // Do what you need to do with the list of authorities
}

You can also use the functional programming style of working, by using the methods that are available on class Optional such as map. For example, if you would want to get just the name of the user in an Optional when it is found, you could do this:

// Transforms the Optional<User> to an Optional<String> containing the username
Optional<String> username = foundUser.map(User::getUsername);

Or a list of the authorities in an Optional:

Optional<List<Authority>> authorities = foundUser.map(User::getAuthorities);

Optional represents an object that either contains a value or nothing. Your repository will return an Optional containing a User object when the user was found, or an empty Optional if the user was not found.

Upvotes: 3

Arnaud
Arnaud

Reputation: 17534

You are calling methods on the Optional object, not the actual User object.

You can retrieve the User object by calling User actualUser = foundUser.get() .

Note that the call to Optional.get() throws NoSuchElementException if there is no value.

Upvotes: 2

Related Questions