JPA #JoinColumn not working properly with REST - java

Im learning Spring Security with REST, and I have 2 MySQL tables, one for users and one for authorities. The user_id from authorities table is foreign key for id from user table. I want to use these roles from authorities table with Spring Security for role-based authorisation. But I have a problem at the begining.
When I try to do a POST request to insert some data in these 2 tables the user_id from authorities table is NULL.
This is the code:
User entity:
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.OneToMany;
#Entity
public class ApplicationUser {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String username;
private String password;
#OneToMany(mappedBy="applicationUser", cascade=CascadeType.ALL)
private List<Authorities> authorities;
public ApplicationUser() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
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 List<Authorities> getAuthorities() {
return authorities;
}
public void setAuthorities(List<Authorities> authorities) {
this.authorities = authorities;
}
}
Authorities entity:
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import com.fasterxml.jackson.annotation.JsonIgnore;
#Entity
public class Authorities {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private long id;
private String role;
#JsonIgnore
#ManyToOne(cascade= {CascadeType.DETACH, CascadeType.MERGE,
CascadeType.PERSIST, CascadeType.REFRESH})
#JoinColumn(name="user_id")
private ApplicationUser applicationUser;
public Authorities() {
}
public long getId() {
return id;
}
public void setId(long id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public ApplicationUser getApplicationUser() {
return applicationUser;
}
public void setUser(ApplicationUser applicationUser) {
this.applicationUser = applicationUser;
}
}
REST Controller:
import java.util.List;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestBody;
import org.springframework.web.bind.annotation.RestController;
#RestController
public class UserController {
#Autowired
private ApplicationUserRepository applicationUserRepository;
#Autowired
private BCryptPasswordEncoder bCryptPasswordEncoder;
#GetMapping("/sign-up")
public List<ApplicationUser> getUsers() {
return applicationUserRepository.findAll();
}
#PostMapping("/sign-up")
public void signUp(#RequestBody ApplicationUser user) {
user.setPassword(bCryptPasswordEncoder.encode(user.getPassword()));
applicationUserRepository.save(user);
}
}
And when I try to do a POST request with this data:
{
"username": "ion",
"password": "1234",
"authorities": [
{
"role": "ROLE_USER"
}
]
}
the response is 200 but the MySQL tables look like this:
So, the user table looks fine, but the authorities table have the user_id cell NULL, and it should be 82.
I want to know how to resolve this problem and any feedback will be appreciated.

Related

Spring Boot "Failed to execute CommandLineRunner Error"

I tried to add One To Many Annotation to my spring boot project, but when I run my project I get "Failed to execute CommandLineRunner " error.
I wanted users in the user's table to have more than one city. So, I tried to add OneToMany Annotation.
You can see the error at the attachment.
User Class
package io.javabrains.springsecurity.jpa.models;
import com.spring.weather.*;
import java.util.*;
import java.util.List;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="app_user")
public class User {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
private int id;
private String userName;
private String password;
private boolean active;
private String role;
private String city;
#OneToMany(targetEntity = UserCity.class,cascade = CascadeType.ALL)
#JoinTable(name="USER_CITY",joinColumns=#JoinColumn(name="m_user_id"),
inverseJoinColumns=#JoinColumn(name="cityId"))
private List<UserCity> usercity;
public User() {
super();
// TODO Auto-generated constructor stub
}
public List<UserCity> getUsercity() {
return usercity;
}
public void setUsercity(List<UserCity> usercity) {
this.usercity = usercity;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 boolean isActive() {
return active;
}
public void setActive(boolean active) {
this.active = active;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public String getCity() {
return city;
}
public void setCity(String city) {
this.city = city;
}
}
User City Class
package io.javabrains.springsecurity.jpa.models;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
#Entity
#Table(name="user_city")
public class UserCity {
#Id
#GeneratedValue(strategy =GenerationType.AUTO)
private int cityId;
private String cityName;
public UserCity() {
super();
// TODO Auto-generated constructor stub
}
public UserCity(int cityId, String cityName, User mUser) {
super();
this.cityId = cityId;
this.cityName = cityName;
this.mUser = mUser;
}
#ManyToOne
private User mUser;
public int getCityId() {
return cityId;
}
public void setCityId(int cityId) {
this.cityId = cityId;
}
public String getCityName() {
return cityName;
}
public void setCityName(String cityName) {
this.cityName = cityName;
}
public User getmUser() {
return mUser;
}
public void setmUser(User mUser) {
this.mUser = mUser;
}
}
User Repository
package io.javabrains.springsecurity.jpa;
import java.util.Optional;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.stereotype.Repository;
import io.javabrains.springsecurity.jpa.models.User;
public interface UserRepository extends JpaRepository<User, Integer> {
Optional<User> findByUserName(String userName);
}
User City Repository
package io.javabrains.springsecurity.jpa;
import org.springframework.data.jpa.repository.JpaRepository;
import io.javabrains.springsecurity.jpa.models.User;
import io.javabrains.springsecurity.jpa.models.UserCity;
public interface CityRepository extends JpaRepository<UserCity,id>{
}
Spring Application Class
package io.javabrains.springsecurity.jpa;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Bean;
import org.springframework.data.jpa.repository.config.EnableJpaRepositories;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import com.spring.weather.WeatherService;
import io.javabrains.springsecurity.jpa.models.User;
import io.javabrains.springsecurity.jpa.models.UserCity;
#SpringBootApplication
#EnableJpaRepositories(basePackageClasses = UserRepository.class)
public class SpringsecurityApplication implements CommandLineRunner{
#Bean
public WeatherService ws() {
return new WeatherService ();
}
#Autowired
UserRepository userRepository;
CityRepository cityRepository;
public static void main(String[] args) {
SpringApplication.run(SpringsecurityApplication.class, args);
}
#Override
public void run(String... args) throws Exception {
// TODO Auto-generated method stub
System.out.println("Application Running.");
User adminUser= new User();
UserCity ucity=new UserCity();
UserCity ucity2=new UserCity();
ucity.setCityName("amsterdam");
adminUser.setUserName("Admin");
adminUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
adminUser.setRole("ROLE_ADMIN");
adminUser.setActive(true);
adminUser.setCity("bologna");
ucity.setmUser(adminUser);
userRepository.save(adminUser);
cityRepository.save(ucity);
User newUser= new User();
newUser.setUserName("User");
newUser.setPassword(new BCryptPasswordEncoder().encode("pass"));
newUser.setRole("ROLE_USER");
newUser.setActive(true);
newUser.setCity("maribor");
ucity2.setmUser(newUser);
userRepository.save(newUser);
cityRepository.save(ucity2);
}
}
The problem you are encountering, more specifically the NullPointerException at line 54 of your main application, is caused by the fact that the cityRepository is not
instantiated.
Looking through your configuration, I see that you only register the UserRepository with the #EnableJpaRepositories annotation.
Try adding also the CityRepository to the #EnableJpaRepositories, and also specify this bean as a candidate for autowiring( also add #Autowired to this bean, as you did for UserRepository)
For a good practice, following the MVC structure, it would be nice is all your spring repositories, the beans responsible for all CRUD operations with the database to be under the same package

Every user have your own listed data when he/she will login by his/her credential

In my project N- number of User is available. Every user can do insert update deleted list of data. every users have different different data. suppose one user have 10 record another user have 20 record and 3rd user have 15 record etc.
I have try to multiple user can register and login to my application with first user in side first user account i have inserted 10 record and display then logout. again i will login with different user then that same data will be display which is inserted by previous user. So my problem is how to maintain every user data with your own account i am beginner in spring-boot with hibernate, jsp.
1.Usercontroller.java
package com.rajesh.controller;
import javax.servlet.http.HttpSession;
import javax.validation.Valid;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.ui.ModelMap;
import org.springframework.validation.BindingResult;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.ResponseBody;
import com.rajesh.model.User;
import com.rajesh.service.UserService;
#Controller
public class UserController {
private final Logger logger = LoggerFactory.getLogger(UserController.class);
#Autowired
private UserService userService;
#GetMapping("/")
public String Home(Model model) {
return "home";
}
#PostMapping("/user/register")
public String registerNewUser(ModelMap model, #ModelAttribute("userRegister")#Valid User user, BindingResult bindingResult) {
User userExists = userService.findUserByEmail(user.getEmail());
if (userExists != null) {
bindingResult
.rejectValue("email", "error.user",
"There is already a user registered with the email provided");
model.addAttribute("msgEmail", "your email is already registered");
logger.info("your email Id is already registered");
System.out.println("your email is already registered");
return "home";
} else {
userService.saveUser(user);
model.addAttribute("successMessage", "User has been registered successfully");
logger.info("User has been registered successfully");
System.out.println("User has been registered successfully");
return "home";
}
}
#PostMapping("/user/login")
public String doLogin(ModelMap model, #ModelAttribute("command")User user, HttpSession session) {
if(userService.loginUser(user.getEmail(), user.getPassword()) != null) {
session.setAttribute("email",user.getEmail());
session.setAttribute("user_id", user.getId());
model.addAttribute("sucessLogin", "You are login sucessfully");
logger.info("You are login sucessfully",user.getEmail());
System.out.println("You are login sucessfully "+ user.getEmail());
return "redirect:userdashboard";
}else {
System.out.println("Invalid Email/Password");
logger.error("Invalid Email/Password");
model.put("failed", "Invalid Email/Password");
return "home";
}
}
#PostMapping("/user/checkstatus")
#ResponseBody
public Integer checkUserStatus(String email, ModelMap model, #ModelAttribute("command")User user, HttpSession session) {
int userStatus = userService.isActiveUserStatus(email);
System.out.println(userStatus);
if(userStatus != 0) {
System.out.println(userStatus);
return userStatus;
}else {
System.out.println(userStatus);
return userStatus;
}
}
#GetMapping("/logout")
public String doLogout(ModelMap model, #ModelAttribute("command")User user, HttpSession session) {
session.removeAttribute("email");
logger.info("you are logout successfully");
return "home";
}
}
User.java
package com.rajesh.model;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
import javax.validation.constraints.Email;
import javax.validation.constraints.NotEmpty;
import org.hibernate.validator.constraints.Length;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Data;
import lombok.NoArgsConstructor;
/**
* #author Rajesh Bhushan
*/
#Data
#Builder
#AllArgsConstructor
#NoArgsConstructor
#Entity
#Table(name = "users")
public class User extends BaseEntity{
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private int id;
#Column(name="shopname")
#Length(min = 3, message = "*Your shopname must have at least 3 characters")
#NotEmpty(message = "*Please provide an shopname")
private String shopname;
#Column(name="name")
#Length(min = 3, message = "*Your name must have at least 3 characters")
#NotEmpty(message = "*Please provide an name")
private String name;
#Column(name="address")
#Length(min = 3, message = "*Your address must have at least 3 characters")
#NotEmpty(message = "*Please provide an address")
private String address;
#Column(name="mobile")
#NotEmpty(message = "*Please provide an address")
private String mobile;
#Column(name = "email")
#Email(message = "*Please provide a valid Email")
#NotEmpty(message = "*Please provide an email")
private String email;
#Column(name = "password")
#NotEmpty(message = "*Please provide your password")
private String password;
#Column(name="active")
private int active;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "user_role", joinColumns = #JoinColumn(name = "user_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles;
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getShopname() {
return shopname;
}
public void setShopname(String shopname) {
this.shopname = shopname;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public String getAddress() {
return address;
}
public void setAddress(String address) {
this.address = address;
}
public String getMobile() {
return mobile;
}
public void setMobile(String mobile) {
this.mobile = mobile;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public int getActive() {
return active;
}
public void setActive(int active) {
this.active = active;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
}
UserRepository.java
package com.rajesh.repository;
import org.springframework.data.jpa.repository.JpaRepository;
import org.springframework.data.jpa.repository.Query;
import org.springframework.stereotype.Repository;
import com.rajesh.model.User;
#Repository
public interface UserRepository extends JpaRepository<User, Long> {
public User findByEmail(String email);
#Query("from User as u where u.email=:email and u.password=:password")
public User loginUser(String email,String password);
#Query("select active from User as u where u.email=:email")
public Integer isActiveUserStatus(String email);
}
4.UserService.java
package com.rajesh.service;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import com.rajesh.model.Role;
import com.rajesh.model.User;
import com.rajesh.repository.RoleRepository;
import com.rajesh.repository.UserRepository;
#Service
public class UserService {
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
public User findUserByEmail(String email) {
return userRepository.findByEmail(email);
}
public void saveUser(User user) {
user.setShopname(user.getShopname());
user.setName(user.getName());
user.setEmail(user.getEmail());
user.setPassword(user.getPassword());
user.setMobile(user.getMobile());
user.setAddress(user.getAddress());
user.setActive(0);
user.setCreatedBy(user.getName());
user.setCreatedDate(new Date());
user.setUpdatedBy(user.getName());
user.setUpdatedDate(new Date());
Role userRole = roleRepository.findByRole("USER");
user.setRoles(new HashSet<Role>(Arrays.asList(userRole)));
userRepository.save(user);
}
public User loginUser(String email,String password) {
return userRepository.loginUser(email, password);
}
public Integer isActiveUserStatus(String email) {
Integer activeStatus = userRepository.isActiveUserStatus(email);
return activeStatus;
}
}
Create a userid column on data table. So when listing data get datas according to userid.

#AuthenticationPrincipal Throws Exception

This test project becouse of I don't know how I inject #AuthenticationPrincipal annotation in method ,I have some problem,#AuthenticationPrincipal UserDetails throws exception
UserDetails userDetails = SecurityContextHolder.getContext().getAuthentication().getPrincipal()
is working not problem but I want to inject this annotation in method how can I do ?
When I added annotation in method this exception is thrown
org.springframework.web.util.NestedServletException: Request processing failed; nested exception is java.lang.IllegalStateException: No primary or default constructor found for interface org.springframework.security.core.userdetails.UserDetails
How can I inject #AuthenticationPrincipal to index method in MainControll class ?
How can I solve this situation ?
MainControll.class
package com.sencerseven.springsecurityauth.controller;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.annotation.AuthenticationPrincipal;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.web.authentication.logout.SecurityContextLogoutHandler;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;
#Controller
public class MainController {
#RequestMapping(value = {"/"})
public ModelAndView index(#AuthenticationPrincipal UserDetails userDetails) {
ModelAndView mv = new ModelAndView("index");
mv.addObject("user", userDetails);
return mv;
}
#RequestMapping(value = {"/login"})
public ModelAndView loginPage(#RequestParam(name="error",required = false)String error,
#RequestParam(name="logout",required = false)String logout) {
ModelAndView mv = new ModelAndView("login");
mv.addObject("userClickLoginPage",true);
return mv;
}
#RequestMapping("/perform-logout")
public String logout(HttpServletRequest httpServletRequest,HttpServletResponse httpServletResponse) {
Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
if(authentication != null) {
new SecurityContextLogoutHandler().logout(httpServletRequest, httpServletResponse, authentication);
}
return "redirect:/";
}
}
This class is my main controller
WebSecurityConfig.class
package com.sencerseven.springsecurityauth.security;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.config.annotation.authentication.builders.AuthenticationManagerBuilder;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.config.annotation.web.configuration.EnableWebSecurity;
import org.springframework.security.config.annotation.web.configuration.WebSecurityConfigurerAdapter;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
#Configuration
#EnableWebSecurity
public class WebSecurityConfig {
#Bean
public static BCryptPasswordEncoder bCryptPasswordEncoder() {
return new BCryptPasswordEncoder();
}
#Configuration
public static class HomeConfigLogin extends WebSecurityConfigurerAdapter {
#Autowired
UserDetailsService userDetailsService;
#Override
protected void configure(AuthenticationManagerBuilder auth) throws Exception {
auth.userDetailsService(userDetailsService).passwordEncoder(bCryptPasswordEncoder());
}
#Override
protected void configure(HttpSecurity http) throws Exception {
http.authorizeRequests().antMatchers("/**").permitAll().and()
.formLogin().loginPage("/login").usernameParameter("username").passwordParameter("password")
.defaultSuccessUrl("/", true).loginProcessingUrl("/login").and().logout().and().exceptionHandling()
.accessDeniedPage("/").and().csrf();
}
}
}
MyUserDetailService
package com.sencerseven.springsecurityauth.security;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import javax.transaction.Transactional;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.security.core.GrantedAuthority;
import org.springframework.security.core.authority.SimpleGrantedAuthority;
import org.springframework.security.core.userdetails.User;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.stereotype.Service;
import com.sencerseven.springsecurityauth.dao.UserDAO;
import com.sencerseven.springsecurityauth.dto.Role;
#Service("userDetailsService")
public class MyUserDetailsService implements UserDetailsService {
#Autowired
private UserDAO userDAO;
#Transactional
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
com.sencerseven.springsecurityauth.dto.User user = userDAO.findByUserName(username);
List<GrantedAuthority> authorities = buildUserAuthority(user.getRole());
return buildUserForAuthentication(user, authorities);
}
private User buildUserForAuthentication(com.sencerseven.springsecurityauth.dto.User user,
List<GrantedAuthority> authorities) {
return new User(user.getUsername(), user.getPassword(), user.isEnabled(), true, true, true, authorities);
}
private List<GrantedAuthority> buildUserAuthority(Set<Role> userRoles) {
Set<GrantedAuthority> setAuths = new HashSet<GrantedAuthority>();
for (Role userRole : userRoles) {
setAuths.add(new SimpleGrantedAuthority(userRole.getRole()));
}
List<GrantedAuthority> Result = new ArrayList<GrantedAuthority>(setAuths);
return Result;
}
}
User.class
package com.sencerseven.springsecurityauth.dto;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.CascadeType;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinColumns;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name = "User")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
private String username;
private String password;
private boolean enabled;
private String email;
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(joinColumns = #JoinColumn(name = "user_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> role;
public User() {
}
public User(String username, String password, boolean enabled, String email, Set<Role> role) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.email = email;
this.role = role;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
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 boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<Role> getRole() {
return role;
}
public void setRole(Set<Role> role) {
this.role = role;
}
#Override
public String toString() {
return "User [id=" + id + ", username=" + username + ", password=" + password + ", enabled=" + enabled
+ ", email=" + email + ", role=" + role + "]";
}
}
Role.class
package com.sencerseven.springsecurityauth.dto;
import java.io.Serializable;
import java.util.Set;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.GenerationType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.Table;
#Entity
#Table(name = "Role")
public class Role implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private int id;
private String role;
#ManyToMany(mappedBy = "role", fetch = FetchType.LAZY)
private Set<User> user;
public Role() {
}
public Role(String role, Set<User> user) {
this.role = role;
this.user = user;
}
public int getId() {
return id;
}
public void setId(int id) {
this.id = id;
}
public String getRole() {
return role;
}
public void setRole(String role) {
this.role = role;
}
public Set<User> getUser() {
return user;
}
public void setUser(Set<User> user) {
this.user = user;
}
#Override
public String toString() {
return "Role [id=" + id + ", role=" + role + ", user=" + user + "]";
}
}
if you use WebMvcConfigurationSupport and #AuthenticationPrincipal than you must add a AuthenticationPrincipalArgumentResolver:
public class WebMvcConfig extends WebMvcConfigurationSupport {
...
#Override
protected void addArgumentResolvers(List<HandlerMethodArgumentResolver> argumentResolvers) {
argumentResolvers.add(new AuthenticationPrincipalArgumentResolver());
}

Many to Many with condition. How can i add limited entries in list based on condition?

I'm creating a dynamic menu using spring and hibernate based on user roles. It works fine and menu is getting generated. but the relationship between menu and submenu doesn't work properly. I want only submenus which has roles assigned to them. but it contains all the submenus.
My POJOs are like below.
Menu.java
package com.pmc.domain;
import java.io.Serializable;
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.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Transient;
import org.hibernate.annotations.Fetch;
#Entity
#Table(name="menu", catalog="test")
public class Menu implements Serializable{
#Id
#Column(name = "menu_item_id")
private Integer menuId;
#ManyToMany(cascade={CascadeType.ALL})
#JoinTable(name="MENU_ROLES",
joinColumns={#JoinColumn(name="menu_item_id")},
inverseJoinColumns={#JoinColumn(name="user_role_id")})
private List<UserRole> userRoles;
#Column(name = "label", length = 100)
private String label;
#Column(name = "link", length = 100)
private String link;
#ManyToOne(cascade={CascadeType.ALL})
#JoinColumn(name = "parent")
private Menu parent;
#OneToMany(mappedBy="parent",fetch = FetchType.EAGER)
private List<Menu> submenus;
public Integer getMenuId() {
return menuId;
}
public void setMenuId(Integer menuId) {
this.menuId = menuId;
}
public List<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(List<UserRole> userRoles) {
this.userRoles = userRoles;
}
public String getLabel() {
return label;
}
public void setLabel(String label) {
this.label = label;
}
public String getLink() {
return link;
}
public void setLink(String link) {
this.link = link;
}
public Menu getParent() {
return parent;
}
public void setParent(Menu parent) {
this.parent = parent;
}
public List<Menu> getSubmenus() {
return submenus;
}
public void setSubmenus(List<Menu> submenus) {
this.submenus = submenus;
}
}
UserRole.java
package com.pmc.domain;
import static javax.persistence.GenerationType.IDENTITY;
import java.util.List;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.UniqueConstraint;
#Entity
#Table (name = "roles", catalog = "test")
public class UserRole {
private Integer userRoleId;
private Set<User> users;
private String role;
private List<Menu> menus;
public UserRole() {
}
public UserRole(Set<User> users, String role) {
this.users = users;
this.role = role;
}
#Id
#GeneratedValue(strategy = IDENTITY)
#Column(name = "user_role_id",
unique = true, nullable = false)
public Integer getUserRoleId() {
return this.userRoleId;
}
public void setUserRoleId(Integer userRoleId) {
this.userRoleId = userRoleId;
}
#ManyToMany(fetch = FetchType.LAZY)
#JoinTable(name="USER_ROLES",
joinColumns={#JoinColumn(name="user_role_id")},
inverseJoinColumns={#JoinColumn(name="username")})
public Set<User> getUsers() {
return this.users;
}
public void setUsers(Set<User> users) {
this.users = users;
}
#Column(name = "role", nullable = false, length = 45)
public String getRole() {
return this.role;
}
public void setRole(String role) {
this.role = role;
}
#ManyToMany(mappedBy="userRoles",fetch = FetchType.EAGER)
public List<Menu> getMenus() {
return menus;
}
public void setMenus(List<Menu> menus) {
this.menus = menus;
}
}
User.java
package com.pmc.domain;
import java.util.HashSet;
import java.util.Set;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.ManyToMany;
import javax.persistence.OneToMany;
import javax.persistence.Table;
#Entity
#Table(name="users", catalog="test")
public class User {
private String username;
private String password;
private boolean enabled;
private Set<UserRole> userRole = new HashSet<UserRole>(0);
public User() {
}
public User(String username, String password, boolean enabled) {
this.username = username;
this.password = password;
this.enabled = enabled;
}
public User(String username, String password,
boolean enabled, Set<UserRole> userRole) {
this.username = username;
this.password = password;
this.enabled = enabled;
this.userRole = userRole;
}
#Id
#Column(name = "username", unique = true,
nullable = false, length = 45)
public String getUsername() {
return this.username;
}
public void setUsername(String username) {
this.username = username;
}
#Column(name = "password",
nullable = false, length = 60)
public String getPassword() {
return this.password;
}
public void setPassword(String password) {
this.password = password;
}
#Column(name = "enabled", nullable = false)
public boolean isEnabled() {
return this.enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
#ManyToMany(mappedBy = "users")
public Set<UserRole> getUserRole() {
return this.userRole;
}
public void setUserRole(Set<UserRole> userRole) {
this.userRole = userRole;
}
}
my query is like this.
select menu from User user, IN (user.userRole) roles, IN(roles.menus) menu where user.username = ?
It gives all the required menus with proper roles to the user. But the list of submenus in each menu is not reflected according to the roles.
Can you please help on this?
Thanks

hibernate4: A Foreign key refering has the wrong number of column. should be 2

I am trying to use Hibernate annotations for writing a model class for my database tables.
I have two tables each having a primary key User and ChartDetails.
package com.winnow.springservice.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
//User Entity class mapped with hibernate
#Entity
#Table(name="User")
#SuppressWarnings(value = { "all" })
public class User implements Serializable
{
#Id
#Column(name="user_id")
public String user_Id;
#Column(name="user_name")
public String userName;
public String password;
#Column(name="last_login")
public String last_Login;
#Column(name="role_id")
public int role_Id;
public int status;
public String getUser_Id() {
return user_Id;
}
public void setUser_Id(String user_Id) {
this.user_Id = user_Id;
}
public String getLast_Login() {
return last_Login;
}
public void setLast_Login(String last_Login) {
this.last_Login = last_Login;
}
public int getRole_Id() {
return role_Id;
}
public void setRole_Id(int role_Id) {
this.role_Id = role_Id;
}
public int getStatus() {
return status;
}
public void setStatus(int status) {
this.status = status;
}
public String getUserName() {
return userName;
}
public void setUserName(String userName) {
System.out.println("username"+userName);
this.userName = userName;
}
public String getPassword() {
return password;
}
public void setPassword(String password)
{
System.out.println("password "+password);
this.password = password;
}
}
Chart details
package com.winnow.springservice.domain;
import java.io.Serializable;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.Table;
#Entity
#Table(name="Chart_Details")
#SuppressWarnings(value = { "all" })
public class ChartDetails implements Serializable
{
#Id
#Column(name="chart_id")
public int chartId;
#Id
#Column(name="chart_type_id")
public int chartTypeId;
#Column(name="chart_name")
public String chartName;
#Column(name="x_axis")
public String x_axis;
#Column(name="y_axis")
public String y_axis;
#Column(name="z_axis")
public int z_axis;
#Column(name="chart_filter_id")
public int chartFilterId;
#Column(name="is_data_table")
public boolean isDataTable;
#Column(name="dataset_id")
public int datasetId;
#Column(name="user_id")
public int userId;
#Column(name="project_id")
public int projectId;
}
And I have one more table – ChartsStarredBy – which has userId and chart_id as foreign keys from the above two tables.
But I am unable to find how I can reference these constraints in the ChartsStarredBy table.
package com.winnow.springservice.domain;
import java.io.Serializable;
import java.util.Date;
import javax.persistence.CascadeType;
import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.ManyToOne;
import javax.persistence.OneToMany;
import javax.persistence.OneToOne;
import javax.persistence.Table;
import javax.persistence.Temporal;
import javax.persistence.TemporalType;
#Entity
#Table(name="Chart_Starred_By")
#SuppressWarnings(value = { "all" })
public class ChartsStarredBy implements Serializable
{
#Id
public int id;
#Temporal(TemporalType.DATE)
public Date starred_date;
#ManyToOne
#JoinColumn(name = "FK_chart_id4")
private ChartDetails chart_details;
#ManyToOne
#JoinColumn(name = "FK_user_id4")
private User user;
public Date getStarred_date()
{
return starred_date;
}
public void setStarred_date(Date starred_date)
{
this.starred_date = starred_date;
}
public User getUser()
{
return user;
}
public void setUser(User user)
{
this.user = user;
}
public ChartDetails getChart_details() {
return chart_details;
}
public void setChart_details(ChartDetails chart_details) {
this.chart_details = chart_details;
}
}
Please help me achieve this? Thanks in advance.
First of all you should create an integer id for User table which is primary key. Here in your code you creating it as String type.
You are doing wrong here
#ManyToOne
#JoinColumn(name = "FK_chart_id4")
private ChartDetails chart_details;
#ManyToOne
#JoinColumn(name = "FK_user_id4")
private User user;
You have IDs in User table & ChartDetails table as
#Id
#Column(name="user_id")
public String user_Id;
AND
#Id
#Column(name="chart_id")
public int chartId;
So when you refer to id of another class you should give name of that id in #JoinColumn. Just like this
#ManyToOne
#JoinColumn(name = "chartId")
private ChartDetails chart_details;
#ManyToOne
#JoinColumn(name = "user_Id")
private User user;
You can also use #ForeignKey(name = "user_Id") annotation from Hibernate like this
#ManyToOne
#ForeignKey(name = "user_Id")
private User user;
Example tutorial :- Hibernate One To Many Annotation Tutorial

Categories