#oneToMany with #JoinTable have unique constraint in jpa? - mysql

I have a two tables which are USER entity have
#OneToMany
#JoinTable(name="user_roles")
private List<Role> roles;
Role Entity have User
#ManyToOne
private User user;
Desc of table user_role is
Name Null
USER_RECORD_ID NOT NULL NUMBER(19)
ROLE_RECORD_ID NOT NULL NUMBER(19)
NOTE: A user can have multiple roles,and i have already created roles through script,have Id:10001,10002,10003 etc
In user_role role table i am inserting one user 800001 with all the roles so the table looks like
USER_RECORD_ID ROLE_RECORD_ID
800001 10001
800001 10002
800001 10003
800002 10001 ///This record will through me unique constraint error
So if i try to give a role to new user where role is predefined it throughs me this error
INSERT INTO USER_ROLE(USER_RECORD_ID,ROLE_RECORD_ID) VALUES(800002,10001)
Error report -
SQL Error: ORA-00001: unique constraint (SYSTEM.UK_LPLHY51JOJA1LP4465QK2E0AF) violated
00001. 00000 - "unique constraint (%s.%s) violated"
*Cause: An UPDATE or INSERT statement attempted to insert a duplicate key.
For Trusted Oracle configured in DBMS MAC mode, you may see
this message if a duplicate entry exists at a different level.
*Action: Either remove the unique restriction or do not insert the key.

I think the error is caused by the use of #ManyToOne/#OneToMany while the relation you have is #ManyToMany. This is so because in the example you give the USER_RECORD_ID with the value 800001 has multiple ROLE_RECORD_ID and the ROLE_RECORD_ID with the value 10001has multiple USER_RECORD_ID.
Therefore try using #ManyToManyinstead, this should fix your problem.
Here is a reference in case you need it: https://en.wikibooks.org/wiki/Java_Persistence/ManyToMany

You have setup your mappings incorrectly, as it seems you have intended to have a bidirectional relationship that uses a relation table but instead have setup two independent relationships. The first, User.roles uses the relation table, but the otherside
#ManyToOne
private User user;
is telling JPA to setup a Role-User relation that uses a foreign key in the Role table. This doesn't seem to be the source of your problem, but will cause you other issues and doesn't match what you are asking for- Your role can only reference a single User, yet you are asking for roles to be assigned multiple users. Try:
#ManyTooMany
#JoinTable(name="user_roles")
private List<Role> roles;
.. and in the Role entity:
#ManyTooMany(mappedby"roles")
private List<User> users;
Also make sure you drop the database schema and let JPA recreate the database using these new mappings.

Related

Is it possible to implement such a database structure in springboot?

I use hibernate as the framework for springboot CUBA operations. But I have a problem, our workout information and recipe information are coming from external API. This means that I only need to store the recipe and workout ids in the database. The database structure is as follows.
DB sturucture
As the data is provided by the API, we have not created corresponding entity tables for workouts and recipes. But then the problem arises. What should be done with the join table in this case. I mean the premise of #manytomany is that two entity tables are needed, and we only have entity tables for users. Even if we use a joint primary key, there is still a need to add user_id as a foreign key in the joint primary key. How can we mark user_id as a foreign key without a workout or recipe entity table?
Your question is quite confusing but I'll try to provide an answer for what I understood.
If the data is completely external, you can map an element collection consisting of ids only:
#Entity
public class User {
// other fields
#ElementCollection
#CollectionTable(name = "recipse_user")
Set<Long> recipeIds;
#ElementCollection
#CollectionTable(name = "workout_user")
Set<Long> workoutIds;
}

MySQL database with multiple user types

I'm designing a MySQL database with some tables for a clinic and I need three different user types: admin, medic and patient.
What I did was to create a table called users where its columns are precisely the common fields shared by admins, medics and patients (there is of course a primary key called id_user which auto increments every time a user is added).
Then I created three tables regarding the specific data for each user type: admin, medic and patient in which I have a field called id_user which is a foreign key to id_user in the table users.
When I tried to establish the foreign key constraint for the three user type tables, phpMyAdmin doesn't allow me to set ON DELETE as "SET NULL" (I think that would make sense because if I delete a user from the users table then it should automatically set the fields as NULL in the medic, admin or patient tables, right?) and gives me the error "relation has not been added".
Doubt 1: What's happening here that I'm not aware of?
Doubt 2: Should I forget this way of relating tables and simply add the specific fields for each user type in the users table although some users will have some fields set as NULL?
Here is an image illustrating my database:
You should use Cascading Deletes instead of setting fields null, if you delete a user you want them gone if you null out the data you'll just have tables filled with nulls.
Also from what i understand you created 3 tables for each of the permission levels if this is the case you should maybe handle that in code with conditions checking the permissions level

Mapping values from foreign keys in table

I'm using hibernate for my project and what i'm essentially trying to do is figure out how to auto-map the values with foreign keys from my table in the database to a data object.
For example, I have a users table with the following columns
id - INT
username - VARCHAR
password - VARCHAR
email - VARCHAR
firstName - VARCHAR
lastName - VARCHAR
This is fairly straightforward to map as there are no foreign keys involved. The code I have is:
SQLQuery q = session.createSQLQuery("SELECT * FROM users WHERE username=? AND password=?");
q.setString(0, username);
q.setString(1, password);
q.addEntity(User.class);
List<User> users = q.list()
Now supposing I add some foreign keys to my user table such as
userlevel_id - INT
department_id - INT
Which reference the user level a user belongs to and the department. How do I get hibernate to map the user level name from the userlevel table and the department name from the department table? It wont be of much use if I just store the id's in the User data object as I will need to display the values to my views later on. Any help will be greatly appreciated, Thanks!!
Use an eagerly loaded #ManyToOne mapping on your User object. Make an object to represent both your Departmentand your UserLevel and add them as fields into your User object. The reason that you should have this mapping as eagerly loaded is that there is never a situation where you don't want to load a User without their Department or UserLevel. Hibernate will automatically map your User object to the appropriate Department and UserLevel.
If you want too, you can make the relationship bi-directional so you can get all users in a department by selecting a department. Anything you can do in SQL you can map using Hibernate.
Have a read of the documentation and see if that helps.

EF4 One to many to one with Db foreign key

I am trying to use code first with an existing db. So far it went well, but now I am failing at a one to many to one relationship.
There is a table customer and a table address in the db where address does NOT have any customerid but a foreign one to many key FK_Address_Customer.
The auto created classes from the edmx look like
Customer:
public int CustomerID (PK)
public Address Address
Address:
public int AddressID (PK)
public HashSet<Customer> Customers
Whatever I do in the fluent API either fails with invalid column Address_AddressID or Multiplicity conflicts with the referential constraint error.
I assumed:
//Customer has one address, address can have multiple customers<br/>
pModelBuilder.Entity<Customer>().HasRequired(m => m.Address).WithMany(x => x.Customers);
//Address has multiple customers, customer has one address<br/>
pModelBuilder.Entity<Address>().HasMany(m => m.Customers).WithRequired();
I got this correct on other tables where there where NO foreign keys in the db by using HasForeignKey, but in the above scenario it does not work. I also tried via MapKey passing the foreign key name also with no luck.
Ho do I get this simple relationship going ?
Thanks
You must tell EF the name of FK in Customer table otherwise it will use default Address_AddressID. HasForeignKey will do the magic.
pModelBuilder.Entity<Customer>()
.HasRequired(c => c.Address)
.WithMany(a => a.Customers)
.HasForeignKey(c => c.AddressID);
Where AddressID is FK property in your Customer entity. If you don't have FK property in the Customer entity you need to use Map:
pModelBuilder.Entity<Customer>()
.HasRequired(c => c.Address)
.WithMany(a => a.Customers)
.Map(m => m.MapKey("AddressID"));
Where AddressID is a name of FK column in Customer table. You always need that column to have one-to-many relation.
The difference between having and not having FK property in your entity make difference between two types of associations supported by EF.

Possible to Fix a Foreign Key in Yii without having set it up in the Database?

I'm using phpMyAdmin for my database GUI and it's connecting to Yii Framework on my website.
I wish for my products table for instance, to have a foreign key department_id which is a reference to the id field of my departments table. Unfortunately, I don't currently have the facility to set the foreign key up properly in phpMyAdmin, so department_id is just an indexed field. I cannot change the configuration of phpMyAdmin at the moment so it's stuck like it is without a foreign key and relationship facility.
Is there a way to modify the Models of these tables in Yii so they link? I know there is a relations function inside the Model Class file that holds this information:
return array('department_id' => array(self::BELONGS_TO, 'Departments', 'id'),
Could I not just add something similar to the above? Is there more legwork? Is it now fixed (as in static, not corrected) because of phpMyAdmin?
Cheers
If I'm not mistaken, you don't need to have mySql enforcing foreign key relationships for them to still work in Yii. Setting up FK constraints in mySql ensures proper database integrity, but I don't think Yii actually uses that at runtime.
When initially running yiic (of Gii) to build the project I think it looks at the DB to build the right relations in the Model, but it doesn't use them after that.
Yii then uses this knowledge (from yiic) of the table relationships to make your life easier by providing shortcut methods to access relational data, and to ensure you don't violate mySql constraints and get ugly SQL errors, etc. But you can still use Yii relation logic without the underlying SQL constraints. The only problem will be that if Yii messes up and assigns a non-existing FK or something, your database will not catch this error (your data integrity will be more error prone).
To link your products to departments, just make sure you have a department_id field in the Product (which it sounds like you do). Then add a relation rule like so to Product:
'department' => array(self::BELONGS_TO, 'Department', 'department_id'),
And in your Department model:
'products' => array(self::HAS_MANY, 'Product', 'department_id'),
Now you should be able to use the relation like normal:
$myProductModel->department; // returns the model of the Department referenced
$myDepartmentModel->products; // returns the models of all Products in the department
Good luck, and let me know if I am way off base and it doesn't work for you!