How to make a double relatiobnship using a Spring Boot project +JPA? - postgresql

Have a project with 4 tables: users, companies, roles and user_roles_relationships.
In the user_roles_relationships have 3 columns: user_id, role_id and company_id.
Each user have a different role for each company.
I use JPA but, how to get all companies from specific user?, for example, in the list companies section need show all companies associated to the current authenticated user.
In SQL is easy, make a inner join using the relationships table and company table and a where clausle, but how to works in the repository?
The ideal query is:
SELECT companies.*
FROM companies
INNER JOIN user_groups_relatinships ON (user_groups_relatinships.company_id = companies.id)
INNER JOIN users ON (users.id = user_groups_relatinships.user_id)
WHERE users.id = ?
I have a tree entities, the user, the company and the role, the user entity have a role relationship using the #ManyToMany annotation, and the company no have relationships annotations.

Related

Website privileges in separate SQL table?

I'm creating a website and I only want certain users to be granted the privilege of creating a post.
I have a table named Accounts where each user's basic information is stored (Id, firstName, lastName, email). Should I include a createPrivilege attribute in the Accounts table?
Or should I create a separate table named Privileges where I have the columns (id, createPrivilege) and the Id is a foreign key referencing the Accounts table's Id attribute?
If "createPrivilege" is an attribute of "Account", and there is only one instance of that attribute for any given entity, the common pattern is to have that as a column in the Account.
However, that approach quickly becomes very messy - you're likely to have many privileges, and adding new columns for each will make the "account" table very messy.
The most common way to model privileges is to introduce the concept of "role". A single user typically has several roles. A role might be "anonymous user", "authenticated user", "moderator", etc.
So, my recommendation would be to have a table with "account", a table called "role", and a join table "account_role" with foreign keys to both.

Query that combines 3 tables

I need to display the names of projects on which employees from the department called "Programmers" work. I am stuck on this query, can someone help me?-
I got three tables.
departments where department id of 3 is Programmers
department_id
name
projects:
p_id
p_name
employees
id,
name,
department_id
SELECT p_name from PROJECTS
WHERE...
Given the three tables you provided I do not think you can do it. There is nothing linking projects to either employees or departments. You will need another table (employeesOnProject or deparmentprojects, etc) to do it.

Roles permissions and user roles, proper mapping?

I have a basic role based access control. Single table for permission (name, description), single table for role (name, description). Question is, how to make proper mapping with the users? So in my mind comes 1 solution:
role_permission_set - table
(role_permission_id PK, role_id (many-to-one), permission_id (many-to-one))
user_role - table
(user_role_id PK, user_id (many-to-one), role_permission_id (many-to-one))
Two tables for mapping roles permissions and users roles. Is there a better way of doing this?
You have this right.
Break it down into two independent many-to-many relationships. One is between user and role. The other is between role and permission.
Each of those two many-to-many relationships will need a join table similar to what you described.
The only mistake I see in your post is that user_role should contain the role_id instead of the role_permission_id.
create table user_role (
user_role_id int serial primary key,
user_id int not null references user(user_id),
role_id int not null references role(role_id),
constraint uq_user_role unique(user_id, role_id)
);
When you want to get a list of permission values for a user:
select distinct p.name
from user_role ur
join role_permission rp on rp.role_id = ur.role_id
join permission p on p.permission_id = rp.permission_id
where ur.user_id = 123;

How would I associate users with different company tables?

In the below diagram you can see I have profiles for users. A user means the profile is associated with a login. If they don't have a login account they are merely a "contact" at the company tables you see on the right.
I am creating a CRM that needs to be able to store many facilities, customers, vendors, etc.
My question is how would I associate that profile with the company it belongs too? If I went to there profile page, for example, I should see what company they work for, regardless of what table the company is in.
I have 2 ideas but both seem flawed. One is to make a separate profile table for contacts for each. Example. vendor_profiles, customer_profiles, etc. This seems messy.
My other idea was to make a vendor_id, customer_id, etc column in the profile table, set them all to NULL by default, and if they belong to a vendor then my application code would check each for a number, and I think you get where I am going from there. Again, seems very messy, and inefficient.
I also considered grouping the Vendors, Customers, so on into one table and just setting a "type" but they all store very different info and are used in different, and often, relational ways.
Introduce a new organization table which unifies those aspects of vendor, customer,
facility and our_company that they all share in common:
CREATE TABLE organization (
organization_id serial4
type text);
CREATE TABLE profile (
profile_id serial4
user_id int4 REFERENCES user
organization_id int4 REFERENCES organization
...);
Then add an organization_id foreign key to vendor, customer, facility and our_company
so these tables can be joined to organization when the extra info in those tables are needed.
CREATE TABLE vendor (
vendor_id serial4
organization_id int4 REFERENCES organization
vendor_specific_field text
...);
Note that if you use "unique" names for id fields (such as organization_id instead of id) which have a consistent meaning across all tables, then you can JOIN ... USING syntax
SELECT *
FROM profile p
INNER JOIN organization o USING (organization_id)
INNER JOIN vendor v USING (organization_id)
WHERE o.type = 'vendor'
instead of
SELECT *
FROM profile p
INNER JOIN organization o ON p.organization_id = o.id
INNER JOIN vendor v ON v.organization_id = o.id
WHERE o.type = 'vendor'
which may improve readability and reduce potential errors in join conditions. (You'll never have to wonder what field in one table connects to the id field in another table.)

How to use where clause in JPQL?

I made a shopping cart web application for a stores. If a customer log into the system, They are adding some items to there shopping cart. In my case, I store that all cart items in table named, ShoppingCart. I have 2 tables named, Customer and ShoppingCart. ShoppingCart primary key is userName. userName is a attribute of Customer table. I need to get all the ShoppingCart entries where userName.
SELECT o FROM ShoppingCart o, Customer c WHERE c.userName = :id
id is the primary key of ShoppingCart. I failed to get correct result from this query. How can I do it?
Thanks in Advance.
You can try the below query. In your query, you haven't added which column should be joined to fetch exact results for the given id.
SELECT o FROM ShoppingCart o, Customer c WHERE c.userName = o.userName AND o.userName = :id
Also, you can try adding relationships one-to-many as each customer can have one or more than that order items.
SELECT c FROM Customer c JOIN c.orders o WHERE c.userName = :id
Here, orders is the collection of orders for particular customer. Then from Customer, you can get its orders.