Reputation: 1
This mapping should return a Set of subscribers or subscriptions. But instead, I get the error:
There was an unexpected error (type=Bad Request, status=400). Failed to convert value of type 'java.lang.String' to required type 'org.project.notablog.domains.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'subscriptions'; nested exception is java.lang.NumberFormatException: For input string: "subscriptions" org.springframework.web.method.annotation.MethodArgumentTypeMismatchException: Failed to convert value of type 'java.lang.String' to required type 'org.project.notablog.domains.User'; nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.lang.Long] for value 'subscriptions'; nested exception is java.lang.NumberFormatException: For input string: "subscriptions"
Controller:
@Controller
@RequestMapping("/user")
public class UserController {
@GetMapping("{type}/{user}/list")
public String userList(
Model model,
@PathVariable User user,
@PathVariable String type
) {
model.addAttribute("userChannel", user);
model.addAttribute("type", type);
if ("subscriptions".equals(type)) {
model.addAttribute("users", user.getSubscriptions());
} else {
model.addAttribute("users", user.getSubscribers());
}
return "subscriptions";
}
}
Entity:
@Entity
@Table(name = "usr")
public class User implements UserDetails {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
@NotBlank(message = "Username cannot be empty")
private String username;
@NotBlank(message = "Password cannot be empty")
private String password;
private boolean active;
@Email(message = "Email isn't correct")
@NotBlank(message = "Email cannot be empty")
private String email;
private String activationCode;
@ElementCollection(targetClass = Role.class, fetch = FetchType.EAGER)
@CollectionTable(name = "user_role", joinColumns = @JoinColumn(name = "user_id"))
@Enumerated(EnumType.STRING)
private Set<Role> roles;
@OneToMany(mappedBy = "author", cascade = CascadeType.ALL, fetch = FetchType.LAZY)
private Set<Message> messages;
@ManyToMany
@JoinTable(
name = "user_subscriptions",
joinColumns = { @JoinColumn(name = "author_id") },
inverseJoinColumns = { @JoinColumn(name = "subscriber_id") }
)
private Set<User> subscribers = new HashSet<>();
@ManyToMany
@JoinTable(
name = "user_subscriptions",
joinColumns = { @JoinColumn(name = "subscriber_id") },
inverseJoinColumns = { @JoinColumn(name = "author_id") }
)
private Set<User> subscriptions = new HashSet<>();
public User() {
}
public User(String username, String password, boolean active, Set<Role> roles) {
this.username = username;
this.password = password;
this.active = active;
this.roles = roles;
}
@Override
public boolean equals(Object o) {
if (this == o) return true;
if (o == null || getClass() != o.getClass()) return false;
User user = (User) o;
return Objects.equals(id, user.id);
}
@Override
public int hashCode() {
return Objects.hash(id);
}
public Boolean isAdmin()
{
return roles.contains(Role.ADMIN);
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getUsername() {
return username;
}
@Override
public boolean isAccountNonExpired() {
return true;
}
@Override
public boolean isAccountNonLocked() {
return true;
}
@Override
public boolean isCredentialsNonExpired() {
return true;
}
@Override
public boolean isEnabled() {
return isActive();
}
public void setUsername(String username) {
this.username = username;
}
public boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
@Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return getRoles();
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getActivationCode() {
return activationCode;
}
public void setActivationCode(String activationCode) {
this.activationCode = activationCode;
}
public Set<Message> getMessages() {
return messages;
}
public void setMessages(Set<Message> messages) {
this.messages = messages;
}
public Set<User> getSubscribers() {
return subscribers;
}
public void setSubscribers(Set<User> subscribers) {
this.subscribers = subscribers;
}
public Set<User> getSubscriptions() {
return subscriptions;
}
public void setSubscriptions(Set<User> subscriptions) {
this.subscriptions = subscriptions;
}
}
Freemarker template:
<#import "parts/common.ftlh" as c>
<@c.page>
<h3>${author.username}</h3>
<div>${type}</div>
<ul class="list-group">
<#list users as user>
<li class="list-group-item">
<a href="/user-messages/${user.id}">${user.getUsername()}</a>
</li>
</#list>
</ul>
</@c.page>
I've already tried everything that came to my mind, but I can't figure out what the problem is.
Upvotes: 0
Views: 9021
Reputation: 471
With this
@PathVariable User user,
you are referring to variable within your path {type}/{user}/list
, which is just a String, probably the userId.
It should be something like
@PathVariable("user") String userId
after which you can load the user, like User user = userService.getUser(userId);
UserService or UserRepository must be wired into the Controller for this.
Upvotes: 1