How to check if username already exists in table? - java

I have the REST API app and when I create a user with the same username it creates all the time, but I want the username to be unique cause in real apps username is unique for each user, how can I provide a checking username in DB?
I want my app to throw some message when I create a user with a username that already exists, and of course, do not save a new user username that already exists
My user Entity:
#Table(name = "usr", uniqueConstraints=
#UniqueConstraint(columnNames={"username", "email"}))
public class User {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
private Long id;
#Column(name = "username")
private String username;
#Column(name = "password")
private String password;
#Column(name = "first_name")
private String firstName;
#Column(name = "last_name")
private String lastName;
#Column(name = "role")
private Role role;
#Column(name = "email")
private String email;
#Column(name = "status")
private Status status;
// #OneToMany(mappedBy = "author")
// private List<Message> messages;
// #OneToMany(mappedBy = "author")
// private List<Comment> comments;
#OneToOne
#JoinColumn(name = "gender_id")
private Gender gender;
#OneToOne
#JoinColumn(name = "address_id")
private Address address;
#ManyToMany
#JoinTable(
name = "user_subscriptions",
joinColumns = #JoinColumn(name = "channel_id") ,
inverseJoinColumns = #JoinColumn(name = "subscriber_id"))
private Set<User> subscribers;
#ManyToMany
#JoinTable(
name = "user_subscriptions",
joinColumns = #JoinColumn(name = "subscriber_id") ,
inverseJoinColumns = #JoinColumn(name = "channel_id"))
private Set<User> subscriptions;
#OneToOne
#JoinColumn(name = "file_id")
private FileEntity fileEntity;
My user service:
#Transactional
public User save(UserRequest user) {
provideAllUserCheckingActionsForSave(user);
User userUntilSave = userMap.userRequestToUser(user,Role.USER,Status.ACTIVE);
userUntilSave.setPassword(passwordEncoder.encode(userUntilSave.getPassword()));
User saved = userRepo.save(userUntilSave);
log.info("User save method invoked");
return saved;
}

You can use #unique annotation to store the unique values in the database and if it throws the exception for not taking the unique value the exception should be handled.

Before create user,you can search user by username,if search result is empty,then create new user,if search result is not empty,deal the question.

You can add validation to the controller or you can simply do it as follows:- When a user wants to register, get the username and search in the database whether it already exists or not. If findByUsername(username) returns null then perform the next operation and register the user, else return some error message.

Related

How do I print User Id in another table

I have user entity in backend and another is feedback entity userid of user table is foreign key to feedback table. I want to print that user id in frontend part. But when I submit any feedback in database it is adding the userid correctly. IN frontend I have created table to display all feedbacks I want to print userid in that table it is coming blank.
This is my feedback entity:
#Entity
#Table(name="feedback")
public class Feedback implements Serializable {
private static final long serialVersionUID = 1L;
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "FEEDBACK_ID")
private int feedbackid;
#Column(name = "FEEDBACK_DATE")
private LocalDate feedbackDate;
#Column(name = "TITLE")
private String title;
#Column(name = "DESCRIPTION")
private String description;
#Column(name = "STATUS")
private String status;
#JsonIgnore
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "USER_ID")
#JsonIncludeProperties({"userId"})
#JsonIgnoreProperties({"userName", "firstName", "lastName",
"dateOfBirth", "email", "mobileno", "password",
"subscriptionStartDate", "subscriptionExpireDate", "subscriptionStatus"})
private User user;
How should I write the Typescript to display user id also

In case of one to one mapping in Java springboot with JPA, I am getting null value

I have two entities like below:
users:
public class User implements Serializable {
#Id #GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long userId;
#Column(nullable = false)
private String userName;
#OneToOne(cascade = CascadeType.ALL, fetch = FetchType.LAZY, mappedBy = "user")
#JoinColumn(name="userId", referencedColumnName = "userId")
private Address address;
}
Address:
public class Address {
#Id #GeneratedValue(strategy = GenerationType.SEQUENCE)
private Long addressId;
private String streetName;
private Long userId;
#OneToOne(fetch = FetchType.LAZY, optional = false)
#JoinColumn(name = "userId", referencedColumnName="userId", insertable = false, updatable = false, nullable = false)
private User user;
}
I am doing userRepository.save(user); with user object as follows:
{
"userName" : "test",
"Address" : {
"streetName" : "street"
}
}
but in Address table, userId is coming as NULL even though there is a forign key relationship is there and when i am getting user entity Address is coming as NULL Can anyone please let me know where i am doing the mistake.
Thanks in advance.
If I changed the above code like this:
User.java
#OneToOne(cascade = CascadeType.ALL)
#JoinColumn(name = "addressId")
private Address address;
Address.java
#OneToOne(mappedBy = "user")
private User user;
It worked fine.

Need to find all Users for a specific role JPA Criteria API

I am implementing a user management system which has the following entities :
public class UserEntity implements Serializable {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column(name = "ID")
Long id;
#Column(unique = true, name = "EMAIL")
private String email;
#Column(name = "NAME")
private String name;
#Column(name = "PASSWORD")
private String password;
#Column(name = "MOBILE")
private String mobile;
#Column(name = "OWNER_ID")
private String ownerId;
#Column(name = "TRAINER_ID")
private String trainerId;
#Column(name = "ADDED_ON")
private Timestamp addedOn;
#Column(name = "MODIFIED_ON")
private Timestamp modifiedOn;
#Column(name = "ADDED_BY")
private String addedBy;
#Column(name = "MODIFIED_BY")
private String modifiedBy;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "USER_ROLES", joinColumns = #JoinColumn(name = "USER_ID", referencedColumnName = "ID"),
inverseJoinColumns =
#JoinColumn(name =
"ROLE_ID", referencedColumnName = "ROLE_ID"))
List<RoleEntity> roles;
#OneToOne(
mappedBy = "user",
cascade = CascadeType.ALL,
orphanRemoval = true,
fetch = FetchType.LAZY
)
private UserStatisticsEntity userStatisticsEntity;
here is the RoleClass :
public class RoleEntity implements GrantedAuthority {
#Id
#Column(name="ROLE_ID")
private String roleId;
#Column(name="ROLE_NAME")
private String roleName;
#ManyToMany(mappedBy = "roles")
private List<UserEntity> users;
#Override
public String getAuthority() {
return this.roleId;
}
}
I would like to fetch all users belonging to a particular role and also be able to add dynamic where clauses on name, mobile, email along with paging etc.
My current code looks like this to fetch selected fields of Users with dynamic where clauses and pagination :
CriteriaBuilder criteriaBuilder = entityManager.getCriteriaBuilder();
CriteriaQuery<TrainerDTO> criteriaQuery = criteriaBuilder.createQuery(TrainerDTO.class);
Root<UserEntity> main = criteriaQuery.from(UserEntity.class);
criteriaQuery.multiselect(main.get("id"), main.get("name"), main.get("email"), main.get("ownerId"), main.get(
"mobile"),
main.get("addedBy"), main.get("modifiedBy"), main.get("addedOn"), main.get("modifiedOn"))
.orderBy(criteriaBuilder.desc(main.get("addedOn")))
.distinct(true);
List<Predicate> predicates = new ArrayList<>();
if (StringUtils.isNotBlank(queryParams.get("mobile"))) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(main.get("mobile"), queryParams.get("mobile"))));
}
if (StringUtils.isNotBlank(queryParams.get("name"))) {
predicates.add(criteriaBuilder.and(criteriaBuilder.like(main.get("name"),
"%" + queryParams.get("name") + "%")));
}
if (StringUtils.isNotBlank(queryParams.get("email"))) {
predicates.add(criteriaBuilder.and(criteriaBuilder.equal(main.get("email"), queryParams.get("email"))));
}
criteriaQuery.where(predicates.toArray(new Predicate[predicates.size()]));
log.info("TrainerDAO::getAllTrainersPaginatedForOwner Query created...");
TypedQuery<TrainerDTO> query = entityManager.createQuery(criteriaQuery);
query.setFirstResult(pageNumber - 1);
query.setMaxResults(pageSize);
return query.getResultList();
I am having two issues here :
How do I get all users which have a certain role? Suppose I need to find all users which have a Role with ROLE_ID = "ROLE_ADMIN".
In my pagination implementation, the last item in repeated on the next page. Suppose User1 was the last item on page 1, he is coming as first item on page 2 as well.
Please suggest on how to proceed further. All help would be appreciated.
Here is my way would be like this:
Issue 1:
You need to reach RoleEntity to check if the role_id is equal to "ROLE_ADMIN", so you need to fetch roles from RoleEntity first and get all the information there.
After you created main object:
Fetch<UserEntity, RoleEntity> fetchedRoles = main.fetch("roles", JoinType.LEFT);
You will append your condition to your predicates list;
predicates.add(criteriaBuilder.equal( fetchedRoles.get( "roleId" ), "ROLE_ADMIN"));
Issue 2:
I will try to share what I would do in this case to help you solve the issue.
Let's say you create the query here, in this method with pageable object, you want to return Page
private Page<Books> getUsersWithAdminRole(String... parameters, Pageable pageable){
//...
List<UserEntity> result = entityManager.createQuery(criteria).setFirstResult((int) pageable.getOffset()).setMaxResults(pageable.getPageSize()).getResultList();
CriteriaQuery<Long> countQuery = criteriaBuilder.createQuery(Long.class);
Root<UserEntity> userCount = countQuery.from(UserEntity.class);
countQuery.select(criteriaBuilder.count(userCount)).where(criteriaBuilder.and(predicates.toArray(newPredicate[predicates.size()])));
Long count = entityManager.createQuery(countQuery).getSingleResult();
Page<UserEntity> userPage = new PageImpl<>(result, pageable, count);
return userPage;
}
I hope, it is helpful

How do i connect one table in a mySQL database to more than one other table via foreign keys?

I have a users table, roles table and a notifications table. The user_id is the foreign key for linking users to notifications.
In my users class i am already accessing another table, roles via its foreignkey, role_id.
As shown
#Data
#Entity
#Table(name = "users")
public class User {`enter code here`
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
#Column
private Long id;
#Column
#NotBlank
#Size(max = 40)
private String username;
// Valid From
#Column
private Date validFrom;
// Valid To
#Column
private Date validTo;
#Column
#NotBlank
#Size(max = 100)
private String password;
#OneToOne(fetch = FetchType.LAZY)
#JoinTable(name = "user_roles",
joinColumns = #JoinColumn(name = "user_id"),
inverseJoinColumns = #JoinColumn(name = "role_id"))
private Role role;
public User() {
}
public User(String username, String password) {
this.username = username;
this.password = password;
}
}
How can i use the #JoinTable annotation to connect to the notifications table?
Its not accepting duplicates.
You must not will use #JoinTable annotation. The #JoinTable annotation is used only to #ManyToMany relationship.
You need create a new Entity with three field, and each field must has the #ManyToOne and #JoinColumn annotation.
For Instance:
#Entity
#Table(name = "table_name")
class NewEntity {
//Id and anothers fields
#ManyToOne
#JoinColumn(name = "user_id")
private Users users;
#ManyToOne
#JoinColumn(name = "role_id")
private Roles roles;
#ManyToOne
#JoinColumn(name = "notification_id")
private Notifications notifications ;
//getters and setters
}

Copy new user with associated roles

What I want to do is get data user and copy to a new user (create a new user). This is what I'm doing:
#Entity
#Table(name = "role")
public class Role {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "role_id")
private int roleId;
#Column(name = "role")
private String role;
public Role() {
}
}
#Entity
#Table(name = "usuario")
public class Users {
#Id
#GeneratedValue(strategy = GenerationType.AUTO)
#Column(name = "user_id")
private int id;
#Column(name = "email")
private String email;
#Column(name = "password", nullable=false, length=60)
private String password;
#Column(name = "name", unique=true, nullable=false, length=6)
private String name;
#Column(name = "last_name")
private String lastName;
#Column(name = "active", nullable=false)
private int active;
#OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER)
#JoinTable(name = "user_role", joinColumns = #JoinColumn(name = "user_id"), inverseJoinColumns = #JoinColumn(name = "role_id"))
private Set<Role> roles;
public Users() {
}
}
I get data from one existing user:
Optional<Users> user = usersRepository.findByName(name);
//create a new User to persist
Users newUser = new Users();
newUser.setName("new name");
newUser.setActive(1);
newUser.setEmail(user.get().getEmail());
newUser.setLastName(user.get().getLastName());
newUser.setPassword(user.get().getPassword());
Set<Role> roles = user.get().getRoles();
newUser.setRoles(roles);
usersRepository.save(newUser);
I get this message:
Found shared references to a collection: model.authentication.Users.roles;
nested exception is org.hibernate.HibernateException: Found shared references to a collection: model.authentication.Users.roles
UPDATE 1 (SOLVED)
Optional<Users> user = usersRepository.findByName(codalojamiento);
Users newUser = new Users();
newUser.setName("new name");
newUser.setActive(1);
newUser.setEmail(user.get().getEmail());
newUser.setLastName(user.get().getLastName());
newUser.setPassword(user.get().getPassword());
Set<Role> newRoles = new HashSet();
Set<Role> roles = user.get().getRoles();
for (Role r : roles) {
newRoles.add(r);
}
newUser.setRoles(newRoles);
usersRepository.save(newUser);
Any suggestion?
Thanks
There are multiple things that could go wrong:
Since you are linking a user to multiple roles, but at the same time, multiple users can have the same role, the relation should be #ManyToMany, not #OneToMany.
Secondly, if you insist on having a #OneToMany relationship, you are linking the new user to the roles of the existing user, so a solution might be to create new roles for that user that are identical to the roles of the first user
Personally, i would suggest using a #ManyToMany, and that should fix the problem
In JPA Find method also flushes the data. Here when you have retreived the user using find method it's moved to managed state.
Then you have taken the roles collection from user object and assigned it to newUser. Now basically you have two entities have same collection references which is not allowed.
Either you can detach user from persistence context before saving newUser or clone the roles collection before adding it to newUser.

Categories

Resources