Spring Mvc- delete user from database - java

I'm developing small Spring MVC application, and I have a problem with delete customer from mysql database. When I delete customer like a admin, customer disappears only in the customer table and remains in the authority and users tables. The question is how to repair it?
User.class
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int usersId;
private String username;
private String password;
private Boolean enabled;
private int customerId;
public int getUsersId() {
return usersId;
}
public void setUsersId(int usersId) {
this.usersId = usersId;
}
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 getEnabled() {
return enabled;
}
public void setEnabled(Boolean enabled) {
this.enabled = enabled;
}
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
}
#Entity
public class Authorities {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int authoritiesId;
private String username;
private String authority;
public int getAuthoritiesId() {
return authoritiesId;
}
public void setAuthoritiesId(int authoritiesId) {
this.authoritiesId = authoritiesId;
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public String getAuthority() {
return authority;
}
public void setAuthority(String authority) {
this.authority = authority;
}
}
#Entity
public class Customer implements Serializable {
private static final long serialVersionUID = 5140900014886997914L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private int customerId;
#NotEmpty(message = "Nazwa użytkownika nie może pozostać pusta!")
private String customerName;
#NotEmpty(message = "Uzupełnij adres email!")
private String customerEmail;
private String customerPhone;
#NotEmpty(message = "Nazwa użytkownika nie może pozostać pusta!")
private String username;
#NotEmpty(message = "Uzupełnij hasło!")
#Size(min = 6, max = 16, message = "Hasło musi zawierać od 6 do 16 znaków!")
private String password;
private boolean enabled;
#OneToOne(mappedBy = "customer", cascade = CascadeType.REMOVE)
#JoinColumn(name = "billingAddressId")
private BillingAddress billingAddress;
#OneToOne(mappedBy = "customer", cascade = CascadeType.REMOVE)
#JoinColumn(name = "shippingAddressId")
private ShippingAddress shippingAddress;
#OneToOne( cascade = CascadeType.REMOVE, mappedBy = "customer")
#JoinColumn(name = "cartId")
#JsonIgnore
private Cart cart;
public int getCustomerId() {
return customerId;
}
public void setCustomerId(int customerId) {
this.customerId = customerId;
}
public String getCustomerName() {
return customerName;
}
public void setCustomerName(String customerName) {
this.customerName = customerName;
}
public String getCustomerEmail() {
return customerEmail;
}
public void setCustomerEmail(String customerEmail) {
this.customerEmail = customerEmail;
}
public String getCustomerPhone() {
return customerPhone;
}
public void setCustomerPhone(String customerPhone) {
this.customerPhone = customerPhone;
}
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 isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public BillingAddress getBillingAddress() {
return billingAddress;
}
public void setBillingAddress(BillingAddress billingAddress) {
this.billingAddress = billingAddress;
}
public ShippingAddress getShippingAddress() {
return shippingAddress;
}
public void setShippingAddress(ShippingAddress shippingAddress) {
this.shippingAddress = shippingAddress;
}
public Cart getCart() {
return cart;
}
public void setCart(Cart cart) {
this.cart = cart;
}
}
#Controller
public class RegisterController {
#RequestMapping("/register")
public String registerCustomer(Model model) {
Customer customer = new Customer();
BillingAddress billingAddress = new BillingAddress();
ShippingAddress shippingAddress = new ShippingAddress();
customer.setBillingAddress(billingAddress);
customer.setShippingAddress(shippingAddress);
model.addAttribute("customer", customer);
return "registerCustomer";
}
#Autowired
private CustomerService customerService;
#RequestMapping(value = "/register", method = RequestMethod.POST)
public String registerCustomerPost(#Valid #ModelAttribute("customer") Customer customer, BindingResult result,
Model model) {
if (result.hasErrors()) {
return "registerCustomer";
}
List<Customer> customerList = customerService.getAllCustomers();
for (int i = 0; i < customerList.size(); i++) {
if (customer.getCustomerEmail().equals(customerList.get(i).getCustomerEmail())) {
model.addAttribute("emailMsg", "Email już istnieje w bazie danych!");
return "registerCustomer";
}
if (customer.getUsername().equals(customerList.get(i).getUsername())) {
model.addAttribute("usernameMsg", "Użytkownik o dane nazwie już istnieje w bazie!");
return "registerCustomer";
}
}
customer.setEnabled(true);
customerService.addCustomer(customer);
return "registerCustomerSuccess";
}
}
#Repository
#Transactional
public class CustomerDaoImpl implements CustomerDao {
#Autowired
private SessionFactory sessionFactory;
public void addCustomer(Customer customer) {
Session session = sessionFactory.getCurrentSession();
customer.getBillingAddress().setCustomer(customer);
customer.getShippingAddress().setCustomer(customer);
session.saveOrUpdate(customer);
session.saveOrUpdate(customer.getBillingAddress());
session.saveOrUpdate(customer.getShippingAddress());
Users newUser = new Users();
newUser.setUsername(customer.getUsername());
newUser.setPassword(customer.getPassword());
newUser.setEnabled(true);
newUser.setCustomerId(customer.getCustomerId());
Authorities newAuthority = new Authorities();
newAuthority.setAuthority("ROLE_USER");
session.saveOrUpdate(newUser);
session.saveOrUpdate(newAuthority);
newAuthority.setUsername(customer.getUsername());
Cart newCart = new Cart();
newCart.setCustomer(customer);
customer.setCart(newCart);
session.saveOrUpdate(customer);
session.saveOrUpdate(newCart);
session.flush();
}
public Customer getCustomerById(int id) {
Session session = sessionFactory.getCurrentSession();
Customer customer = (Customer) session.get(Customer.class, id);
session.flush();
return customer;
}
public List<Customer> getAllCustomers() {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from Customer ");
List<Customer> customerList = query.list();
return customerList;
}
public Customer getCustomerByUsername(String username) {
Session session = sessionFactory.getCurrentSession();
Query query = session.createQuery("from Customer where username = ?");
query.setString(0, username);
return (Customer) query.uniqueResult();
}
public void deleteCustomer(Customer customer) {
Session session = sessionFactory.getCurrentSession();
session.delete(customer);
session.flush();
}
}

You have to add foreign key constraints between tables and set action as(on delete= cascade).

Your customer entity doesn't have any relationship with user and authority tables, then no delete is performed by jpa.
EDIT
In customer entity instead of username you could have
#OneToOne(mappedBy="username", cascadeType=CascadeType.REMOVE) private User user
The same for Authories entity:
#OneToOne(mappedBy="username", cascadeType=CascadeType.REMOVE) private User user

On your opinion ,the relationship between User and Customer is one to one.And you want to delete User when you delete the Customer .
First we have to explicit the relationship.
In the User Entity , i suggest you to remove the CustomerId , And add User user to Customer Entity.
And the Customer Entity will be :
private User user;
public void setUser(User user){
this.user = user;
}
#OneToOne
public User getUser(){
return this.user;
}
After that ,you can get the User by customer(userId),And when you want to delete the Customer ,you should get the User first,then delete Customer and delete that User

Related

Don't know how to findByRole to return a customised list of users

I am trying to list users in my application based on role. I have an endpoint in my controller which tries to call my userService class .findByRoles method but I dont know how to put the role I want to without having the role as a string(wont work).
adminController.java method:
#GetMapping(path="/users")
public String showUsers( Model model){
var userList = (List<User>) userService.findByRoles("ROLE_TEACHER"); // dont know how to pass a role here
model.addAttribute("userList", userList);
return "users";
}
User.java:
#Entity
#Table(name = "user_table", schema = "public")
public class User {
#Id
#Column(name = "user_id")
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long user_id;
#Column(name = "name")
private String name;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "email")
private String email;
#Column(name = "confirmed")
private boolean confirmed;
#ManyToMany(cascade = {CascadeType.MERGE, CascadeType.PERSIST, CascadeType.DETACH}, fetch = FetchType.EAGER)
#JoinTable(
name = "user_role_table",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id", referencedColumnName = "role_id"))
private Collection<Role> roles = new HashSet<>();
/*******************************************
* Setters and getters
*******************************************/
public Long getId() {
return user_id;
}
public void setName(String name) {
this.name = name;
}
public String getName() {
return name;
}
public void setUsername(String username) {
this.username = username;
}
public String getUsername() {
return username;
}
public void setPassword(String password) {
this.password = password;
}
public String getPassword() {
return password;
}
public void setEmail(String email) {
this.email = email;
}
public String getEmail() {
return email;
}
public void setConfirmed(Boolean confirmed) {
this.confirmed = confirmed;
}
public Boolean getConfirmed() {
return confirmed;
}
public void setRoles(Collection roles) {
this.roles = roles;
}
public Collection<Role> getRoles() { return this.roles;
}
}
userRepository:
public interface UserRepository extends JpaRepository<User, Long> {
User findByUsername(String username);
User findByEmail(String email);
User findByRoles(Role role);
}
roleRepository:
public interface RoleRepository extends JpaRepository<Role, Long> {
Role findByName(String name);
}
IUserService.java:
public interface IUserService {
User registerNewUserAccount(UserDto userDto);
List<User> findAll();
Optional<User> findById(Long id);
User findByRoles(Role role);
public void delete(Long id);
public User updateConfirmed(Long id);
}
UserService.java method:
#Override
public User findByRoles(Role role) {
return userRepository.findByRoles(role);
}
Any tips how I can go about to fix this issue?
After tweaking around with the classes I think the most logical method to fix the issue is to use roleRepository method findByName. Furthermore, created findAllByRoles in userRepository, IUserService & UserService for returning a list(check my comment on this answer).
Changed IUserService.java to:
public interface IUserService {
User registerNewUserAccount(UserDto userDto);
List<User> findAll();
Optional<User> findById(Long id);
List<User> findAllByRoles(String roles); //Added this new method (VERY IMPORTANT for returning multiple users)
User findByRoles(String roles);
public void delete(Long id);
public User updateConfirmed(Long id);
}
Changed UserService.java method to:
#Override
public User findByRoles(String roles) {
return userRepository.findByRoles(roleRepository.findByName(roles)); // Using roleRepository here
}
// Added below findAllbyRoles to return a list
#Override
public List<User> findAllByRoles(String roles){
return userRepository.findAllByRoles(roleRepository.findByName(roles));
}
Changed adminController.java method to:
#GetMapping(path="/users")
public String showUsers( Model model){
List<User> userList = userService.findAllByRoles("ROLE_STUDENT");
userList.addAll(userService.findAllByRoles("ROLE_TEACHER"));
model.addAttribute("userList", userList);
return "users";
}

TransientPropertyValueException: object references an unsaved transient instance - save the transient instance before flushing

I'm trying to store user details into the following tables: user, role, user_role. When trying to save the details, it throws the following error.
Error during managed flush
[org.hibernate.TransientPropertyValueException: object references an
unsaved transient instance - save the transient instance before
flushing
Here user_role is the parent table, user and role tables are the children. I tried with cascade = CASCADE.ALL. Even though it trows the same error.
User.java
#Entity
public class User implements UserDetails, Serializable{
private static final long serialVersionUID = 902783495L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name="Id", nullable=false, updatable = false)
private Long id;
private String username;
private String password;
private String email;
private boolean enabled = true;
#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 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 void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
Set<GrantedAuthority> authorities = new HashSet<>();
userRoles.forEach(ur -> authorities.add(new Authority(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;
}
}
Role.java
#Entity
public class Role implements Serializable{
private static final long serialVersionUID = 890245234L;
#Id
private int roleId;
private String name;
#OneToMany(mappedBy = "role", cascade=CascadeType.ALL, fetch = FetchType.LAZY)
private Set<UserRole> userRoles = new HashSet<>();
public Role(){}
public int getRoleId() {
return roleId;
}
public void setRoleId(int roleId) {
this.roleId = roleId;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Set<UserRole> getUserRoles() {
return userRoles;
}
public void setUserRoles(Set<UserRole> userRoles) {
this.userRoles = userRoles;
}
}
UserRole.java
#Entity
#Table(name="user_role")
public class UserRole implements Serializable {
private static final long serialVersionUID = 890345L;
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long userRoleId;
public UserRole () {}
public UserRole (User user, Role role) {
this.user = user;
this.role = role;
}
#ManyToOne(fetch = FetchType.EAGER)
#JoinColumn(name = "user_id")
private User user;
#ManyToOne(fetch = FetchType.EAGER)
private Role role;
public long getUserRoleId() {
return userRoleId;
}
public void setUserRoleId(long userRoleId) {
this.userRoleId = userRoleId;
}
public User getUser() {
return user;
}
public void setUser(User user) {
this.user = user;
}
public Role getRole() {
return role;
}
public void setRole(Role role) {
this.role = role;
}
}
Here role_id is primary key and you are trying to set 1 as role_id every time, make new primary key with
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private long seqNo;

error when I try to login with Spring & JPA?

I'm trying to login with users from database, but I have this error. I think the problem appears in class "UserDetailsServiceImpl". What I have to do to fix this error? I will be grateful for any hint or idea...........................................................................
2018-03-16 11:13:40.389 ERROR 6520 --- [nio-8080-exec-5]
w.a.UsernamePasswordAuthenticationFilter : An internal error occurred while trying to authenticate the user.org.springframework.security.authentication.InternalAuthenticationServiceException: failed to lazily initialize a collection of role: com.continental.qtools.fingerprints.models.User.roles, could not initialize proxy - no Session
at org.springframework.security.authentication.dao.DaoAuthenticationProvider.retrieveUser(DaoAuthenticationProvider.java:126) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.authentication.dao.AbstractUserDetailsAuthenticationProvider.authenticate(AbstractUserDetailsAuthenticationProvider.java:144) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:174) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.authentication.ProviderManager.authenticate(ProviderManager.java:199) ~[spring-security-core-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.authentication.UsernamePasswordAuthenticationFilter.attemptAuthentication(UsernamePasswordAuthenticationFilter.java:94) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.authentication.AbstractAuthenticationProcessingFilter.doFilter(AbstractAuthenticationProcessingFilter.java:212) ~[spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.authentication.logout.LogoutFilter.doFilter(LogoutFilter.java:116) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
at org.springframework.security.web.FilterChainProxy$VirtualFilterChain.doFilter(FilterChainProxy.java:331) [spring-security-web-4.2.3.RELEASE.jar:4.2.3.RELEASE]
This is entity "User"
#Entity
#Table(name = "users")
public class User implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#Column(name = "user_id")
#GeneratedValue(strategy = GenerationType.AUTO)
private int userId;
#Column(name = "username")
#NotEmpty(message = "*Please provide your username")
private String username;
#Column(name = "password")
#Length(min = 5, message = "*Your password must have at least 5 characters")
#NotEmpty(message = "*Please provide your password")
private String password;
#Column(name = "email")
#Email(message = "*Please provide a valid Email")
#NotEmpty(message = "*Please provide an email")
private String email;
#Transient
private String passwordConfirm;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "users_roles", joinColumns = #JoinColumn(name = "user_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles;
#ManyToMany(cascade = CascadeType.ALL)
#JoinTable(name = "users_projects", joinColumns = #JoinColumn)
private List<Project> projects;
public User(String username, String password, String email, String passwordConfirm, Set<Role> roles,
List<Project> projects) {
super();
this.username = username;
this.password = password;
this.email = email;
this.passwordConfirm = passwordConfirm;
this.roles = roles;
this.projects = projects;
}
public User() {
// TODO Auto-generated constructor stub
}
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public int getUserId() {
return userId;
}
public String getPassword() {
return password;
}
public void setPassword(String password) {
this.password = password;
}
public String getPasswordConfirm() {
return passwordConfirm;
}
public void setPasswordConfirm(String passwordConfirm) {
this.passwordConfirm = passwordConfirm;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
public List<Project> getProjects() {
return projects;
}
public void setProjects(List<Project> projects) {
this.projects = projects;
}
public Set<Role> getRoles() {
return roles;
}
public void setRoles(Set<Role> roles) {
this.roles = roles;
}
#Override
public String toString() {
return "User [username=" + username + ", password=" + password + ", email=" + email + ", passwordConfirm="
+ passwordConfirm + ", roles=" + roles + ", projects=" + projects + "]";
}
}
This is entity "Role"
#Entity
#Table(name = "roles")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "role_id")
private int id;
#Column(name = "role")
private String role;
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;
}
}
UserDetailsServiceImp
#Service
public class UserDetailsServiceImpl implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#Override
public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
User user = userRepository.findByUsername(username);
System.out.println("User: " + user.getUsername());
Set<GrantedAuthority> grantedAuthorities = new HashSet<>();
for (Role role : user.getRoles()) {
grantedAuthorities.add(new SimpleGrantedAuthority(role.getRole()));
}
return new org.springframework.security.core.userdetails.User(user.getUsername(), user.getPassword(),
grantedAuthorities);
}
}
Try adding a FetchType.EAGER to the roles property on the user object.
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "users_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id")
)
private Set<Role> roles;
Update: Alternative refactor with Privileges included
Authority Class instead of Role Class
#Entity
#Table(name = "authority")
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Authority implements GrantedAuthority {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
private String name;
#ManyToMany
#JoinTable(
name = "authorities_privileges",
joinColumns = #JoinColumn(
name = "authority_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(
name = "privilege_id", referencedColumnName = "id"))
private Collection<Privilege> privileges;
public Authority() {
super();
}
public Authority(final String name) {
super();
this.name = name;
}
public Authority(String name,
Collection<Privilege> privileges) {
this.name = name;
this.privileges = privileges;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public Collection<Privilege> getPrivileges() {
return privileges;
}
public void setPrivileges(Collection<Privilege> privileges) {
this.privileges = privileges;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((name == null) ? 0 : name.hashCode());
return result;
}
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (obj.toString().equals(this.name)) {
return true;
}
if (getClass() != obj.getClass()) {
return false;
}
final Authority auth = (Authority) obj;
if (this.name != null && this.name.equals(auth.name)) {
return true;
}
return false;
}
#Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("Role [name=").append(name).append("]").append("[id=").append(id).append("]");
return builder.toString();
}
#Override
#JsonIgnore
public String getAuthority() {
return name;
}
}
Privilege Class (Optional)
#Entity
#JsonInclude(JsonInclude.Include.NON_NULL)
public class Privilege {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "id")
private Long id;
private String name;
public Privilege() {
super();
}
public Privilege(final String name) {
super();
this.name = name;
}
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
}
User Class
#Entity
#Table(name = "user_account")
public class User implements UserDetails {
#Id
#Column(unique = true, nullable = false)
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "username")
private String username;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "email")
private String email;
#JsonIgnore
#Column(name = "password", length = 60)
private String password;
#Column(name = "enabled")
private boolean enabled;
#Column(name = "last_password_reset_date")
private Timestamp lastPasswordResetDate;
#Column(name = "is_using_2FA")
private boolean isUsing2FA;
#JsonIgnore
#Column(name = "secret", length = 60)
private String secret;
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_authority",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "authority_id", referencedColumnName = "id"))
private Collection<Authority> authorities;
public User() {
this.secret = UUID.randomUUID().toString();
this.enabled = false;
}
public User(Long id,
String username, String firstName, String lastName,
String email, String password,
boolean enabled, Timestamp lastPasswordResetDate,
boolean isUsing2FA, String secret,
Collection<Authority> authorities) {
this.id = id;
this.username = username;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
this.password = password;
this.enabled = enabled;
this.lastPasswordResetDate = lastPasswordResetDate;
this.isUsing2FA = isUsing2FA;
this.secret = secret;
this.authorities = authorities;
}
public Long getId() {
return id;
}
public void setId(final Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(final String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(final String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(final String username) {
this.email = username;
}
public String getPassword() {
return password;
}
public void setPassword(final String password) {
Date date = new Date();
this.lastPasswordResetDate = new Timestamp(date.getTime());
this.password = password;
}
#Override
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public boolean isUsing2FA() {
return isUsing2FA;
}
public void setUsing2FA(boolean isUsing2FA) {
this.isUsing2FA = isUsing2FA;
}
public String getSecret() {
return secret;
}
public void setSecret(String secret) {
this.secret = secret;
}
#Override
public Collection<? extends GrantedAuthority> getAuthorities() {
return this.authorities;
}
#Override
public boolean isEnabled() {
return enabled;
}
public void setEnabled(boolean enabled) {
this.enabled = enabled;
}
public Timestamp getLastPasswordResetDate() {
return lastPasswordResetDate;
}
public void setLastPasswordResetDate(Timestamp lastPasswordResetDate) {
this.lastPasswordResetDate = lastPasswordResetDate;
}
#JsonIgnore
#Override
public boolean isAccountNonExpired() {
return true;
}
#JsonIgnore
#Override
public boolean isAccountNonLocked() {
return true;
}
#JsonIgnore
#Override
public boolean isCredentialsNonExpired() {
return true;
}
#Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = (prime * result) + ((username == null) ? 0 : username.hashCode());
return result;
}
#Override
public boolean equals(final Object obj) {
if (this == obj) {
return true;
}
if (obj == null) {
return false;
}
if (getClass() != obj.getClass()) {
return false;
}
final User user = (User) obj;
if (!username.equals(user.username)) {
return false;
}
return true;
}
#Override
public String toString() {
final StringBuilder builder = new StringBuilder();
builder.append("User [id=").append(id).append(", firstName=").append(firstName).append(", lastName=").append(lastName).append(", email=").append(email).append(", password=").append(password).append(", enabled=").append(enabled).append(", isUsing2FA=")
.append(isUsing2FA).append(", secret=").append(secret).append(", roles=").append(authorities).append("]");
return builder.toString();
}
}
UserBuilder Class
public class UserBuilder {
private Long bId;
private String bUsername;
private String bFirstName;
private String bLastName;
private String bEmail;
private String bPassword;
private boolean bEnabled;
private Timestamp bLastPasswordResetDate;
private boolean bIsUsing2FA;
private String bSecret;
private Collection<Authority> bAuthorities;
public UserBuilder() {
}
public UserBuilder(Long bId,
String bUsername, String bFirstName, String bLastName,
String bEmail, String bPassword, boolean bEnabled,
Timestamp bLastPasswordResetDate, boolean bIsUsing2FA, String bSecret,
Collection<Authority> authorities) {
this.bId = bId;
this.bUsername = bUsername;
this.bFirstName = bFirstName;
this.bLastName = bLastName;
this.bEmail = bEmail;
this.bPassword = bPassword;
this.bEnabled = bEnabled;
this.bLastPasswordResetDate = bLastPasswordResetDate;
this.bIsUsing2FA = bIsUsing2FA;
this.bSecret = bSecret;
this.bAuthorities = bAuthorities;
}
public UserBuilder(User user) {
this.bId = user.getId();
this.bUsername = user.getUsername();
this.bFirstName = user.getFirstName();
this.bLastName = user.getLastName();
this.bEmail = user.getEmail();
this.bPassword = user.getPassword();
this.bEnabled = user.isEnabled();
this.bLastPasswordResetDate = user.getLastPasswordResetDate();
this.bIsUsing2FA = user.isUsing2FA();
this.bSecret = user.getSecret();
}
public User createUser() {
return new User(bId,
bUsername,
bFirstName,
bLastName,
bEmail,
bPassword,
bEnabled,
bLastPasswordResetDate,
bIsUsing2FA,
bSecret,
bAuthorities
);
}
public UserBuilder bId(Long bId) {
this.bId = bId;
return this;
}
public UserBuilder bUsername(String bUsername) {
this.bUsername = bUsername;
return this;
}
public UserBuilder bFirstName(String bFirstName) {
this.bFirstName = bFirstName;
return this;
}
public UserBuilder bLastName(String bLastName) {
this.bLastName = bLastName;
return this;
}
public UserBuilder bEmail(String bEmail) {
this.bEmail = bEmail;
return this;
}
public UserBuilder bPassword(String bPassword) {
Date date = new Date();
this.bLastPasswordResetDate = new Timestamp(date.getTime());
this.bPassword = bPassword;
return this;
}
public UserBuilder bEnabled(boolean bEnabled) {
this.bEnabled = bEnabled;
return this;
}
public UserBuilder bLastPasswordResetDate(Timestamp bLastPasswordResetDate) {
this.bLastPasswordResetDate = bLastPasswordResetDate;
return this;
}
public UserBuilder bIsUsing2FA(boolean bIsUsing2FA) {
this.bIsUsing2FA = bIsUsing2FA;
return this;
}
public UserBuilder bSecret(String bSecret) {
this.bSecret = bSecret;
return this;
}
public UserBuilder bAuthorities(Collection<Authority> bAuthorities) {
this.bAuthorities = bAuthorities;
return this;
}
}
CustomUserDetailsService Class
#Service("userDetailsService")
#Transactional
public class CustomUserDetailsService implements UserDetailsService {
#Autowired
private UserRepository userRepository;
#SuppressWarnings("unchecked")
#Override
public UserDetails loadUserByUsername(final String identity) throws UsernameNotFoundException {
try {
final User user = Optional.ofNullable(userRepository.findByEmail(identity)).orElseGet(() -> userRepository.findByUsername(identity));
if (user == null) {
throw new UsernameNotFoundException("No user found with username: " + identity);
}
//Collection<Authority> authorities = getAuthorities((Collection<Authority>) user.getAuthorities());
Collection<Authority> authorities = getAuthorities((Collection<Authority>) user.getAuthorities());
return new UserBuilder(user).bAuthorities(authorities).createUser();
} catch (final Exception e) {
throw new RuntimeException(e);
}
}
private final Collection<Authority> getAuthorities(final Collection<Authority> authorityList) {
return getGrantedAuthorities(getAuthorityList(authorityList));
}
private final List<String> getAuthorityList(final Collection<Authority> authorityList) {
final List<String> authorities = new ArrayList<String>();
for (final Authority authority : authorityList) {
authorities.add(authority.getName());
if (authority.getPrivileges() == null || authority.getPrivileges().isEmpty()) continue;
// Add all Privileges as Authorities
for (final Privilege item : authority.getPrivileges()) {
authorities.add(item.getName());
}
}
return authorities;
}
private final Collection<Authority> getGrantedAuthorities(final List<String> authorityList) {
final List<Authority> grantedAuthorities = new ArrayList<Authority>();
for (final String authority : authorityList) {
grantedAuthorities.add(new Authority(authority));
}
return grantedAuthorities;
}
}
Repos
public interface PrivilegeRepository extends JpaRepository<Privilege, Long> {
Privilege findByName(String name);
#Override
void delete(Privilege privilege);
}
public interface RoleRepository extends JpaRepository<Authority, Long> {
Authority findByName(String name);
#Override
void delete(Authority role);
}
public interface UserRepository extends JpaRepository<User, Long> {
User findByEmail(String email);
User findByUsername(String username);
#Override
void delete(User user);
}
SetupDataLoader Class (Optional)
#Component
public class SetupDataLoader implements ApplicationListener<ContextRefreshedEvent> {
private boolean alreadySetup = false;
#Autowired
private UserRepository userRepository;
#Autowired
private RoleRepository roleRepository;
#Autowired
private PrivilegeRepository privilegeRepository;
#Autowired
private PasswordEncoder passwordEncoder;
#Autowired
BeerRepository beerRepository;
#Override
#Transactional
public void onApplicationEvent(final ContextRefreshedEvent event) {
if (alreadySetup) {
return;
}
// == create initial privileges
final Privilege userReadPrivilege = createPrivilegeIfNotFound("USER_READ_PRIVILEGE");
final Privilege userWritePrivilege = createPrivilegeIfNotFound("USER_WRITE_PRIVILEGE");
final Privilege beerReadPrivilege = createPrivilegeIfNotFound("BEER_READ_PRIVILEGE");
final Privilege beerWritePrivilege = createPrivilegeIfNotFound("BEER_WRITE_PRIVILEGE");
final Privilege passwordPrivilege = createPrivilegeIfNotFound("CHANGE_PASSWORD_PRIVILEGE");
// == create initial roles
final List<Privilege> adminPrivileges = new ArrayList<Privilege>(Arrays.asList(beerReadPrivilege, beerWritePrivilege, userReadPrivilege, userWritePrivilege, passwordPrivilege));
final List<Privilege> userPrivileges = new ArrayList<Privilege>(Arrays.asList(beerReadPrivilege, beerWritePrivilege));
final Authority adminAuthority = createRoleIfNotFound("ROLE_ADMIN", adminPrivileges);
createRoleIfNotFound("ROLE_USER", userPrivileges);
// == create initial user
createUserIfNotFound("rdurden",
"rdurden#example.com",
"Rupert",
"Durden",
"ILikeBeer2!",
new ArrayList<Authority>(Arrays.asList(adminAuthority)));
alreadySetup = true;
}
#Transactional
Privilege createPrivilegeIfNotFound(final String name) {
Privilege privilege = privilegeRepository.findByName(name);
if (privilege == null) {
privilege = new Privilege(name);
privilege = privilegeRepository.save(privilege);
}
return privilege;
}
#Transactional
Authority createRoleIfNotFound(final String name, final Collection<Privilege> privileges) {
Authority authority = roleRepository.findByName(name);
if (authority == null) {
authority = new Authority(name);
}
authority.setPrivileges(privileges);
authority = roleRepository.save(authority);
return authority;
}
#Transactional
User createUserIfNotFound(final String username, final String email, final String firstName, final String lastName, final String password, final Collection<Authority> authorities) {
User user = Optional.ofNullable(userRepository.findByEmail(email)).orElseGet(() -> userRepository.findByUsername(username));
if (user != null) return user;
Calendar cal = Calendar.getInstance();
cal.add(Calendar.MONTH, -1);
Date lastMonthDate = cal.getTime();
Timestamp lastMonthTimestamp = new Timestamp(lastMonthDate.getTime());
user = new UserBuilder()
.bAuthorities(authorities)
.bUsername(username)
.bFirstName(firstName)
.bLastName(lastName)
.bEmail(email)
.bPassword(passwordEncoder.encode(password))
.bIsUsing2FA(false)
.bEnabled(true)
.bLastPasswordResetDate(lastMonthTimestamp)
.createUser();
user = userRepository.save(user);
return user;
}
}
Try adding #Transactional to method loadUserByUsername.

delete object with a manytomany collection

Sitiuation: trying to remove a person that has a collection of persons(friends). Ofcourse i don't want the friends to be delete so i have to be carefull with that.
code for Person:
#Entity
public class Person {
private String naam, voornaam, email, password;
#Id
private String username;
private String status;
#ManyToMany
private Collection<Person> vrienden;
#OneToMany(orphanRemoval = true)
private Collection<Post> posts;
#Enumerated(EnumType.STRING)
private Role role;
public Person(String naam, String voornaam, String email, String password, String username) {
setNaam(naam);
setEmail(email);
setStatus("online");
setVoornaam(voornaam);
setPassword(password);
setUsername(username);
vrienden = new HashSet<>();
posts = new HashSet<>();
role = Role.USER;
}
public static void addFriend(Person a, Person b) {
a.addFriend(b);
b.addFriend(a);
}
private void addFriend(Person b) {
this.vrienden.add(b);
}
public static void deleteFriend(Person a, Person b) {
a.deleteFriend(b);
b.deleteFriend(a);
}
private void deleteFriend(Person a) {
this.vrienden.remove(a);
}
public Collection<Person> getFriends() {
return vrienden;
}
public Role getRole() {
return this.role;
}
public void setRole(Role role) {
this.role = role;
}
#NotNull(message = "{error.no.name}")
#Size(min = 2, message = "{error.invalid.namesize}")
public String getNaam() {
return naam;
}
public void setNaam(String naam) {
this.naam = naam;
}
#NotNull(message = "{error.no.surnaam}")
#Size(min = 2, message = "{error.invalid.surnamesize}")
public String getVoornaam() {
return voornaam;
}
public void setVoornaam(String voornaam) {
this.voornaam = voornaam;
}
#NotNull(message = "{error.no.email}")
#Email(message = "{error.invalid.email}")
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
#NotNull(message = "{error.no.status}")
#Size(min = 1, message = "{error.no.valid.status}")
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
#NotNull(message = "{error.no.username}")
#Size(min = 2, message = "{error.invalid.usernamesize}")
public String getUsername() {
return username;
}
public void setUsername(String username) {
this.username = username;
}
public void setPassword(String password) {
this.password = Password.getSaltedHash(password);
}
public boolean isPasswordCorrect(String password) {
boolean result = false;
result = Password.check(password, this.password);
return result;
}
#NotNull(message = "{error.no.password}")
#Size(min = 2, message = "{error.invalid.usernamesize}")
public String getPassword() {
return this.password;
}
public void addPost(Post p) {
if (p == null) {
throw new DomainException("Post is null");
}
posts.add(p);
}
public void deletePost(Post p) {
if (p == null) {
throw new DomainException("Post is null");
}
posts.remove(p);
}
public Collection<Post> getPosts() {
return posts;
}
#Override
public int hashCode() {
int hash = 3;
hash = 59 * hash + Objects.hashCode(this.username);
return hash;
}
public void setHashedPassword(String password) {
this.password = password;
}
}
The method that i'm currently using is:
public void DeletePerson(String user) {
entityManager.getTransaction().begin();
entityManager.createQuery("delete from Person p where p.username=:username").setParameter("username", user).executeUpdate();
entityManager.getTransaction().commit();
}
It gives the following error:
java.sql.SQLIntegrityConstraintViolationException: DELETE on table 'PERSON' caused a violation of foreign key constraint 'PRSNPRSNVRNDNSRNME' for key (vincent). The statement has been rolled back.
My guess is to add something to the manytomany annotation
create tables:
https://i.stack.imgur.com/zS2Xf.png
UPDATE:
The code that i use now for deleting succesfully:
public void DeletePerson(String user) {
entityManager.getTransaction().begin();
entityManager.createNativeQuery("delete from PERSON_PERSON p where p.PERSON_USERNAME=?username or p.VRIENDEN_USERNAME=?username").setParameter("username", user).executeUpdate();
entityManager.flush();
Person tempPerson = getPerson(user);
entityManager.remove(tempPerson);
entityManager.getTransaction().commit();
}
but now i still retrieve old references although the data is deleted in the tables. I retrieve that data with:
entityManager.find(Person.class, user);
You cannot delete person that exists as friend in list of another person. First you should remove it from all friend lists (vrienden) in other person objects (rows in db) and than remove it. Error message clearly says that you cannot delete row because that record is FK in other table.
You need to First Delete all Posts and vrienden (Relation - Maybe some intermediate table) then remove current Person (Because Foreign Key Constraint will not allow you to do this - As many other rows from different table may depend on this table.
https://stackoverflow.com/a/1089008/5284920

JPA code not executing further after transaction.commit

Main method
EntityManagerFactory emf=Persistence.createEntityManagerFactory("manager1");
EntityManager em1=emf.createEntityManager();
EntityTransaction entityTransaction=em1.getTransaction();
entityTransaction.begin();
Person persons=JPA_basic_Example.setPerson();//fills all the fields of person
Credential cred=JPA_basic_Example.setCredential();//fills all fields of credentials
System.out.println("check1");
cred.setPerson(persons);
persons.setCredential(cred);
em1.persist(cred);
entityTransaction.commit();
em1.close();
emf.close();
Java Bean Credential oneToone Bidirectional with Person
public class Credential {
#Id
#Column(name ="credentialid")
private int credential_id;
private String UserName;
private String Password;
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name="Personid")
private Person person;
public String getPassword() {
return Password;
}
public void setPassword(String password) {
Password = password;
}
public int getCredential_id() {
return credential_id;
}
public void setCredential_id(int credential_id) {
this.credential_id = credential_id;
}
public String getUserName() {
return UserName;
}
public void setUserName(String userName) {
UserName = userName;
}
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Java Bean Person
#Entity
public class Person {
#Id
#Column(name ="Personid")
private int person_id;
//#Basic(optional = false)
//#Column(name ="Name", unique = true)
private String name;
#ElementCollection
#CollectionTable
List<String> contact=new ArrayList<String>();
private Address address=new Address();
#OneToOne(mappedBy = "person", orphanRemoval = true )
Credential credential ;
public Credential getCredential() {
return credential;
}
public void setCredential(Credential credential) {
this.credential = credential;
}
public List<String> getContact() {
return contact;
}
public void setContact(List<String> contact) {
this.contact = contact;
}
public Address getAddress() {
return address;
}
public void setAddress(Address address) {
this.address = address;
}
public String getName() {
return name;
}
public void setName(String name) {
this.name = name;
}
public int getPerson_id() {
return person_id;
}
public void setPerson_id(int person_id) {
this.person_id = person_id;
}
}
Output Console
Hibernate:
insert
into
Person
(area, city, pincode, state, name, Personid)
values
(?, ?, ?, ?, ?, ?)
AFter this code stuck and nit moving forward nor showing any exceptions or errors

Categories

Resources