Property or field ‘id’ cannot be found on object of type ‘java.lang.Boolean’ – maybe not public or not valid?

Tags: , ,



I am writing a SpringBoot application for an e-commerce website project where I’m creating a form to change the current password of the user account. I am getting the following two errors when the form gets submitted.

  1. ERROR-1
An error happened during template parsing (template: "class path resource [templates/myprofile.html]")

Caused by: org.attoparser.ParseException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)

Caused by: org.thymeleaf.exceptions.TemplateProcessingException: Exception evaluating SpringEL expression: "user.id" (template: "myprofile" - line 110, col 68)
  1. ERROR-2
Property or field 'id' cannot be found on object of type 'java.lang.Boolean' - maybe not public or not valid?

HomeController

@RequestMapping(value = "/updateUserInfo", method = RequestMethod.POST)
      public String updateUserInfo(
              
              @ModelAttribute("user") user user,
              @ModelAttribute("newPassword") String newPassword,
              Model model
              ) throws Exception{
          
          user currentUser = userService.findById(user.getId());
          
          if(currentUser == null) {
              throw new Exception ("User not found.");
          }
          
          if(userService.findByEmail(user.getEmail())!=null) {
              if(userService.findByEmail(user.getEmail()).getId() != currentUser.getId()) {
                  model.addAttribute("emailExists", true);
                  return "myprofile";
              }
          }
          
          if(userService.findByUsername(user.getUsername())!=null) {
              if(userService.findByUsername(user.getUsername()).getId() != currentUser.getId()) {
                  model.addAttribute("usernameExists", true);
                  return "myprofile";
              }
          }
          
          if(newPassword != null && !newPassword.isEmpty() && !newPassword .equals("")) {
              BCryptPasswordEncoder passwordEncoder = SecurityUtility.passwordEncoder();
              String dbPassword = currentUser.getPassword();
              if(passwordEncoder.matches(user.getPassword(), dbPassword)) {
                  currentUser.setPassword(passwordEncoder.encode(newPassword));
              }else {
                  model.addAttribute("invalidPassword", true);
                  return "myprofile";
              }
          }
          
          currentUser.setFirstName(user.getFirstName());
          currentUser.setLastName(user.getLastName());
          currentUser.setUsername(user.getUsername());
          currentUser.setEmail(user.getEmail());
          
          userService.save(currentUser);
          
          model.addAttribute("updateSuccess", true);
          model.addAttribute("user", true);
          model.addAttribute("classActiveEdit", true);
          
          UserDetails userDetails = userSecurityService.loadUserByUsername(currentUser.getUsername());
            
            Authentication authentication = new UsernamePasswordAuthenticationToken(userDetails, userDetails.getPassword(), userDetails.getAuthorities());
            
            SecurityContextHolder.getContext().setAuthentication(authentication); 
            
            return "myprofile";
      }

myprofile.html

<form th:action="@{/updateUserInfo}" method="post" >
                                    <input type="hidden" name="id" th:value="${user.id}" />
                                    <div class="bg-info" th:if="${updateUserInfo}">User info updated</div>

                                    <div class="form-group">
                                        <div class="row">
                                            <div class="col-xs-6">
                                                <label for="firstName">First Name</label>
                                                <input type="text" class="form-control" id="firstName" name="firstName" th:value="${user.firstName}" />
                                            </div>

                                            <div class="col-xs-6">
                                                <label for="lastName">Last Name</label>
                                                <input type="text" class="form-control" id="lastName" name="lastName" th:value="${user.lastName}" />
                                            </div>

                                        </div>
                                    </div>

                                    <div class="form-group">
                                        <label for="userName">Username</label>
                                        <input type="text" class="form-control" id="userName" name="username" th:value="${user.username}" />
                                     </div>

                                    <div class="form-group">
                                        <label for="currentPassword">Current Password</label>
                                        <input type="password" class="form-control" id="currentPassword" name="password" th:value="${currentPassword}" />
                                    </div>
                                    <p style="color: #828282">Enter your current password to change the email address or password</p>

                                    <div class="form-group">
                                        <label for="email">Email Address</label>
                                        <input type="text" class="form-control" id="email" name="email" th:value="${user.email}" />
                                    </div>
                                    <p style="color: #828282">A valid email address. All
                                        emails from the system will be sent to this address.The
                                        email address is not make public and will only be used if
                                        you wish to receive a new password or wish to receive
                                        certain notification</p>

                                    <div class="form-group">
                                        <label for="txtNewPassword">Password</label>&nbsp;<span id="checkPasswordMatch" style="color:red;"></span>
                                        <input type="password" class="form-control" id="txtNewPassword" name="txtNewPassword"  />
                                    </div>

                                    <div class="form-group">
                                        <label for="txtConfirmPassword">Confirm Password</label>
                                        <input type="password" class="form-control" id="txtConfirmPassword" />
                                    </div>
                                    <p style="color: #828282">To change the current user password, enter new password in both fileds </p>


                                    <button id="updateUserInfobutton" type="submit" class="btn btn-primary">Save All</button>
                   </form>

User Class

package com.eshop.domian;

import java.util.Collection;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;

import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.userdetails.UserDetails;

import com.eshop.security.UserRole;
import com.eshop.security.auth;
import com.fasterxml.jackson.annotation.JsonIgnore;

@Entity
public class user implements UserDetails{
    
    @Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name="id", nullable = false, updatable = false)
    private Long id;
    private String firstName;
    private String lastName;
    private String username;
    private String password;
    
    @Column(name="email", nullable = false, updatable = false)
    private String email;
    private String phone;
    private boolean enabled=true;
    
    @OneToOne(cascade = CascadeType.ALL, mappedBy = "user")
    private ShoppingCart shoppingCart;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private List<UserShipping> userShippingList;
    
    @OneToMany(cascade = CascadeType.ALL, mappedBy = "user")
    private List<UserPayment> userPaymentList;
    
    @OneToMany(mappedBy = "user", cascade=CascadeType.ALL, fetch=FetchType.EAGER)
    @JsonIgnore
    private Set<UserRole> userRoles= new HashSet<>();
    
    
    public long getId() {
        return id;
    }
    public void setId(Long id) {
        this.id = id;
    }
    public String getFirstName() {
        return firstName;
    }
    public void setFirstName(String firstName) {
        this.firstName = firstName;
    }
    public String getLastName() {
        return lastName;
    }
    public void setLastName(String lastName) {
        this.lastName = lastName;
    }
    public String getUsername() {
        return username;
    }
    public void setUsername(String username) {
        this.username = username;
    }
    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 getPhone() {
        return phone;
    }
    public void setPhone(String phone) {
        this.phone = phone;
    }
    public void setEnabled(boolean enabled) {
        this.enabled = enabled;
    }
    public Set<UserRole> getUserRoles() {
        return userRoles;
    }
    public void setUserRoles(Set<UserRole> userRoles) {
        this.userRoles = userRoles;
    }
    
    public ShoppingCart getShoppingCart() {
        return shoppingCart;
    }
    public void setShoppingCart(ShoppingCart shoppingCart) {
        this.shoppingCart = shoppingCart;
    }
    public List<UserShipping> getUserShippingList() {
        return userShippingList;
    }
    public void setUserShippingList(List<UserShipping> userShippingList) {
        this.userShippingList = userShippingList;
    }
    public List<UserPayment> getUserPaymentList() {
        return userPaymentList;
    }
    public void setUserPaymentList(List<UserPayment> userPaymentList) {
        this.userPaymentList = userPaymentList;
    }
    @Override
    public Collection<? extends GrantedAuthority> getAuthorities() {
        Set<GrantedAuthority> authorities = new HashSet<>();
        userRoles.forEach(ur -> authorities.add(new auth(ur.getRole().getName())));
        
        return authorities;
    }
    @Override
    public boolean isAccountNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }
    @Override
    public boolean isAccountNonLocked() {
        // TODO Auto-generated method stub
        return true;
    }
    @Override
    public boolean isCredentialsNonExpired() {
        // TODO Auto-generated method stub
        return true;
    }
    
    @Override
    public boolean isEnabled()
    {
        return enabled;
    }
}

User Service

package com.eshop.service;

import java.util.Set;

import com.eshop.domian.UserBilling;
import com.eshop.domian.UserPayment;
import com.eshop.domian.UserShipping;
import com.eshop.domian.user;
import com.eshop.security.PasswordResetToken;
import com.eshop.security.UserRole;

public interface UserService {
    
    PasswordResetToken getPasswordResetToken(final String token);
    
     void createPasswordResetTokenForUser(final user user, final String token);
     
     user findByUsername(String username);

     user findByEmail(String email);
     
     user findById(Long Id);

     user createUser(user user, Set<UserRole> userRoles) throws Exception;

     user save(user user);
     
     void updateUserBilling(UserBilling userBilling, UserPayment userPayment, user user);
     
     void setUserDefaultPayment(Long userPaymentId, user user);
     
     void updateUserShipping(UserShipping userShipping, user user);
     
     void setUserDefaultShipping(Long userShippingId, user user);

}

User Service Implementation

package com.eshop.service.impl;

@Service
public class UserServiceImpl implements UserService{

private static final Logger LOG = LoggerFactory.getLogger(UserService.class);

@Autowired
private PasswordResetTokenRepository passwordResetTokenRepository;

@Autowired
private UserRepository userRepository;

@Autowired
private RoleRepository roleRepository;

@Autowired
private UserPaymentRepository userPaymentRepository;

@Autowired
private UserShippingRepository userShippingRepository;

@Override
public PasswordResetToken getPasswordResetToken(final String token) {
    return passwordResetTokenRepository.findByToken(token);
}

@Override
public void createPasswordResetTokenForUser(final user user, final String token) {
    final PasswordResetToken myToken = new PasswordResetToken(token, user);
    passwordResetTokenRepository.save(myToken);
}

@Override
public user findByUsername(String username) {
    // TODO Auto-generated method stub
    return userRepository.findByusername(username);
}

@Override
public user findById(Long id) {
    return userRepository.findById(id).get(); 
}

@Override
public user findByEmail(String email) {
    // TODO Auto-generated method stub
    return userRepository.findByEmail(email);
}

}

Answer

Here you try to access the id field of the user model attribute:

<input type="hidden" name="id" th:value="${user.id}" />

Here you set the user model attribute to true, therefore it’s of type boolean:

model.addAttribute("user", true);

As a variable of type boolean does not have a field called id, trying to access it gives the error you see. I assume what’s going on is that you didn’t want to set that model attribute to true (perhaps you wanted to set it to currentUser?), or that the id field that you want to access belongs to another model attribute.



Source: stackoverflow