Many-to-many relationship in Java using DAO pattern - java

I am creating a web application only using Java and not any framework.
I am at this point where I have to get data from the Database. I am doing this using DAO pattern but I have a problem to understand some logic about relationships (one-to-one, one-to-many, and many-to-many).
To understand my problem better I will explain by taking an exact example.
I have two entities (tables) in the database User and Role. The entity User has attributes id, name, lastname, username, and password, and the table Role has attributes id, role, description.
From this I have the relation that one User can have more than one Role (so a user can be both a simple user and an admin of the web app), and one Role can be in many User. From this point I creat another table tha represents many-to-many relationship named UserRoles that has attributes user_id, role_id.
Now in Java I have a class named `User:
public class User
{
private int id; (with getters and setters)
private String name; (with getters and setters)
private String lastname; (with getters and setters)
private String username; (with getters and setters)
private String password; (with getters and setters)
// and two constructors with and without parameters together with toString method
}
and the interface named UserDAO:
public interface UserDAO
{
public User find(intid);
public User find(String email, String password);
public List<User> users();
public void create(User user);
public void update(User user);
public void delete(User user);
public boolean existEmail(String email);
public void changePassword(User user);
}
I have the class for manipulation with MySQL queries named UserDAOJDBC:
public class UserDAOJDBC implements UserDAO
{
private static final String FIND_BY_ID = "SELECT * FROM user WHERE id=?";
#Override
public User find(int id) {
return find(FIND_BY_ID, id);
}
private User find(String sql, Object... values){
User user = null;
try {
ResultSet resultSet = DBConnectionPool.executeQuery(sql, values);
if(resultSet.next()){
user = new User();
user.setId(Integer.parseInt(resultSet.getString("id")));
user.setName(resultSet.getString("name"));
user.setLastname(resultSet.getString("lastname"));
user.setUsername(resultSet.getString("username"));
user.setPassword(resultSet.getString("password"));
}
DBConnectionPool.getConnection().close();
} catch (Exception e) {
System.out.println(e);
}
return user;
}
}
Now when I want to get Role for one User what is a better practice?
So far I have this solution:
1) I have to include Role in the User class:
public class User
{
private int id; (with getters and setters)
private String name; (with getters and setters)
private String lastname; (with getters and setters)
private String username; (with getters and setters)
private String password; (with getters and setters)
private List<Role> roles; (with getters and setters)
// and two constructors with and without parameters together with toString method
}
and create in class UserDAOJDBC a method named findWithRoles that makes the join with the tables as:
SELECT * FROM user AS u INNER JOIN userroles as ur ON u.id = ur.user_id
and then the second query that goes through results of the previous one:
SELECT * FROM role AS r INNER JOIN userroles as ur ON r.id = ur.role_id
and from the ResultsSet of this query to populate the array List<Role> roles.

You don't need to include Role into the User class (even though you can). It is enough to create the UserRoles table and read the data from it. You should probably create UserRolesDAO class that will implement all the methods for you to find all the roles of a specific user, and all the users to specific role, as well as save new user, role combination and read it back.
I have an example on github where I combined Students and Courses in exactly same way using JDBC and DAO pattern so feel free to take a look.
Blog post about dao

Related

Java JPA enum-like String options

I am trying to implement a simple User-Roles relationship in a Spring application, for security. The basic entities (some fields and annotations trimmed):
User
#Table(name="usr")
public class User implements Serializable {
#Id
private UUID id;
#ManyToMany(fetch=FetchType.EAGER)
#JoinTable(name="user_roles", joinColumns=#JoinColumn(name="user_id", referencedColumnName="id"),
inverseJoinColumns=#JoinColumn(name="role_id", referencedColumnName="id"))
private Collection<Role> roles;
}
Role
public class Role implements Serializable {
#Id
private UUID id;
#ManyToMany(mappedBy="roles")
private Collection<User> users;
private String name;
}
So far, so good. However, I also have a class that defines a list of role-name values:
UserRoles
public class UserRole {
public static final String ADMIN = "admin";
public static final String USER = "user";
}
I want to constrain the values of the Role's name field to the values in UserRoles, effectively like an enum.
These role values will get used within Spring Security functions that require roles to be string values. As such, if I were to make UserRoles an enum, any database storage would be of ints – the ordinal definition position within UserRoles – which would force me to keep any potentially deprecated options, and also require a hacky conversion every time I need to convert the role to a string that can be passed around in a JWT, etc. (If I want to look at my database directly, it will also be far less informative.)
Is there some way to define Role's name field as limited to the static values in UserRoles? (Changing how or where these values are stored is entirely acceptable.)
You can define like this
public enum UserRoleEnum {
USER, ADMIN
}
And in entity
#Enumerated(EnumType.ORDINAL)
private UserRoleEnum role;

Access Few Columns of a table from CrudRepository in Spring Boot

I have an interface which is extending crud repository
public interface PersonRepo extends CrudRepository<Person, String> {
#Query(value="select name from PERSON where addr=?1", nativeQuery = true)
List<Person> getPeronUsingAddress(String addr);
}
Person entity looks like this:
class Person {
private String name;
private String phoneNumber;
private String address;
//along with getters setters and all basic hibernate annotation to persist and retrieve
}
the person object is saved into the databse and at the time of retrieving the native query is working fine as hibernate executes correct query. But I am not able to get the return type.
If the return type is List of Person then I am getting InvalidDataAccessResourceUsageException
If I create an interface and use the list of interface as return type like
interface response {
String getName();
}
List of Response interface getPeronUsingAddress(String addr);
then I am getting proxy object in the service. I am not able to get the datas from proxy object.
Another approach I did is to use List of object as return type. But it is not possible to downcast to my Person Object.
How to do that.? Or is there any other solution by which I can return selective columns from crud repository and get a Java object with those selected Columns.
In order to fetch selected columns from an entity, you can do like below :
class Person {
private Integer id;
private String name;
private String phoneNumber;
private String address;
//along with getters setters and all basic hibernate annotation to persist and retrieve
}
Create a DTO or Java Object like below :
public class PersonDTO {
private Integer id;
private String name;
private String phoneNumber;
private String address;
public PersonDTO(Integer id, String name, String phoneNumber, String address) {
// logic here
}
//If you want just want name and phone number.
public PersonDTO(String name, String phoneNumber) {
// logic here
}
// you can't create overridden constructors as all members are of same type and at runtime program won't be able to differentiate unless you provide some logic for it.
// getters, setters, any other methods here...
}
Now below will be you Query but it's not native, if you want to keep native query then you will need to use ResultTransformer like here
#Query("select new your.package.PersonDTO(p.name, p.phoneNumber) from Person p where p.id = :id")
public PersonDTO getPersonById(Integer id);

How to decide if a separate entity and DAO is needed for an association table?

How to decide if a separate entity and DAO is needed for an association table?
Suppose I have 3 tables: user, role and user_role. user_role is the association table.
create table user (user_id int not null primary key, login varchar(50) not null unique key, password varchar(100))
create table role (role_id int not null primary key, description varchar(100))
create table user_role (user_role_id int not null identity(1,1) primary key, user_id int not null foreign key references user(user_id), role_id int not null foreign key references role(role_id))
Now I will have separate entities and DAOs for user and role tables.
public class User {
private int userId;
private String login;
private String password;
// getters and setters
}
public interface UserDAO {
User getUserById(int userId);
void insertUser(User user);
void updateUserById(User user);
void deleteUserById(User user);
}
public class Role {
private int roleId;
private String description;
// getters and setters
}
public interface RoleDAO {
User getRoleById(int roleId);
void insertRole(Role role);
void updateRoleById(Role role);
void deleteRoleById(Role role);
}
I will have 3 screens:
Screen 1: I will have a screen to maintain CRUD operations on user table.
Screen 2: I will have a screen to maintain CRUD operations on role table.
Screen 3: I will have a screen where users will be assigned to roles.
But I am confused about how to tackle the user_role table.
a) Should User entity have a list of associated Role. And thats enough?
public class User {
private int userId;
private String login;
private String password;
private Set<Role> roles;
// getters and setters
}
b) Should Role entity have a list of associated User. And thats enough?
public class Role {
private int roleId;
private String description;
private Set<User> users;
// getters and setters
}
c) Should I have a separate entity and DAO for user_role table like this:
public class UserRole {
private int userRoleId;
private User user;
private Role role;
}
public interface UserRoleDAO {
User getUserRoleById(int userRoleId);
void insertUserRole(UserRole userRole);
void updateUserRoleById(UserRole userRole);
void deleteUserRoleById(UserRole userRole);
}
I guess as it a bidirectional relationship between user and roles you should have to have set of roles in User.java and set of users in Roles.java. An separate entity user_roles is definitely required. If you have dao for user you can have below methods in userdao
User getUserRoleById(int userRoleId);
void insertUserRole(UserRole userRole);
void updateUserRoleById(UserRole userRole);
void deleteUserRoleById(UserRole userRole);

Java Persistence Many to Many relationship with self

I have a user class, users should have a list of friends. Friends are also users so every user should have many friends and obviously each of those friends(users) also have many friends(users).
So a many-to-many relationship of users is what I've assumed so far. This is currently the code I have been using (with hibernation JPA annotations)
Here is my MyUser code:
#Entity
public class MyUser {
#Id
private String username;
private String userPassword;
#ManyToMany
#JoinTable(
name="USR_USR",
joinColumns={#JoinColumn(name="USR1_ID", referencedColumnName="USERNAME")},
inverseJoinColumns={#JoinColumn(name="USR2_ID", referencedColumnName="USERNAME")})
private List<MyUser> friends = new ArrayList<MyUser>();
public void setUsername(String username) {
this.username = username;
public void setUserPassword(String userPassword) {
this.userPassword = userPassword;
}
public String getUsername() {
return username;
public String getUserPassword() {
return userPassword;
}
public void setFriends(List<MyUser> friends) {
this.friends = friends;
}
public List<MyUser> getFriends() {
return friends;
}
I'm trying to create a second table by joining the USERNAME column with itself (which doesn't really sound right to me I'll be honest.)
So I'm trying to create a relationship in my database where each MyUser can have many MyUser's.
I'm pretty stuck with this so some help would be appreciated.
Thanks a lot!
I would suggest changing your database schema to something like this:
MyUser(id, ....);
Friends(id1, id2);
Where MyUser.id is the primary key of MyUser, and Friends id1 and id2 are foreign keys to MyUser.id.
This is a pretty common pattern that will give you less problems in the future, and is a bit more maintainable. User A (w/ ID 1) is friends with User B (w/ ID 2) if there is a tuple in the Friends database (1, 2).
Hope that helps,

User Authentication with Hibernate

im new in hibernate.
I would like to build a simple autentication / login system in java with hibernate.
So let's say, i have a class User
public class User {
private int id;
private String username;
private String passwordHash;
...
}
Now i have a DAO to store a new User, and to get all users (as a list). Now im wondering, if its possible to get a list of users without the passwordHash field (for security reason)?
It would be nice if it was a question of configuration.
An other idea would be to split the User class into
public class User {
private int id;
private String username;
...
}
public class UserWithPassword extends User {
private String passwordHash;
...
}
So i could use UserWithPassword to store a new user into the database and use
the User class to query the list of all users (without password).
Any other suggestion?
Your split class won't work because you have to link a class to Hibernate.
Your DAO doesn't have to return the class itself. You can write an HQL query such:
select username
from User
See?
Then your DAO would have a method like public Collection getUserNames()
you can use
java.util.List temp = hibernateTemplate.find("select u from user u ");
you can take all user from temp;
but if you want authenticate,you can use spring security,i suggest

Categories