Hibernate one to Many insertion - mysql

In my location table i have list of employee DO and Employee table has locationid as a foreign key ,if i try to insert location DO using ORM-insert, locationid is inserted in the location table but it is null in the employee table. please help me with this issue. thanks in advance
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL, mappedBy ="location")
private List<Employee> employees = new ArrayList<Employee>();
#ManyToOne(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinColumn(name = "locationid")
private Location location = null;

Related

Spring delete row of join table

I have two entities User:
public class User {
#Id
#GeneratedValue(strategy=GenerationType.IDENTITY)
private Long userID;
#Column(name = "userHashedPassword")
private String password;
#Column(name = "userName")
private String userName;
#Column(name = "userEmail")
private String email;
#Transient
private List<String> groups = new LinkedList<>();
#ManyToMany
#JoinTable(name = "UserRoles",
joinColumns = #JoinColumn(
name = "userID"),
inverseJoinColumns = #JoinColumn(
name = "roleID"))
private Set<Role> roles = new HashSet<>();
#OneToMany(mappedBy = "user")
private Set<Rating> ratings;
protected User(){}
public User(String userHashedPassword, String userName, String email, Set<Role> roles){
this.password = userHashedPassword;
this.userName = userName;
this.email = email;
this.roles = roles;
}
//getters and setters
}
And Group:
#Table(name="FocusGroups")
#Entity
#JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class,
property = "groupID")
public class Group {
#Id
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long groupID;
private String groupName;
#ManyToMany
#JoinTable(name = "GroupMembers",
joinColumns = #JoinColumn(
name = "groupID"),
inverseJoinColumns = #JoinColumn(
name = "userID"))
private Set<User> groupMembers = new HashSet<>();
#ManyToOne(fetch = FetchType.EAGER, optional = true)
#JoinColumn(name="frameworkID", nullable = true)
private Framework framework;
public Group(){}
public Group(String groupName, Set<User> groupMembers, Framework framework) {
this.groupName = groupName;
this.groupMembers = groupMembers;
this.framework = framework;
}
//getters setters
}
When I delete a User, I want to remove them from group members, however it fails due to foreign key constraint: java.sql.SQLIntegrityConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (capripol.groupmembers, CONSTRAINT FK98tbu0sjfsn1m5p340dn0v8wo FOREIGN KEY (userID) REFERENCES users (userID))
How do I work around this?
Well, I will try to answer: First of all, it is rather strange you refer on Groups in user
entity like that:
#Transient
private List<String> groups = new LinkedList<>();
It this case, you will not have a column group in user table in database, hence you have to first perform removal from group_members for an all groups:
delete from group_members where userid = <user_id_you_want_to_remove>;
And only after your JoinTable table does not contain any refers to user with <user_id_you_want_to_remove>, than you can execute
delete from users where userid = 1;
Note: there is no matter you do it by spring data (e.g. deleteById(Long id) and using #Query annotation specify the query above in SQL or HQL, up to you) - this will work. But I highly recommend you to reconsider you database structure - it is not cute to store only one entity.

Cannot delete or update a parent row ConstraintViolationException

I have 2 object entities (User and Phone) and they are supposed to have many-to-many relations.
User.java
//all columns
#ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
#JoinTable(name = "USER_PHONE",
joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "phone_id", referencedColumnName = "id"))
private List<Phone> phones;
Phone.java
//all columns
#ManyToMany(cascade = CascadeType.MERGE, fetch = FetchType.EAGER)
#JoinTable(name = "USER_PHONE",
joinColumns = #JoinColumn(name = "phone_id", referencedColumnName = "id"),
inverseJoinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"))
private List<User> userList;
Now, I add 2 users with IDs 1 and 2 in my USER table.
Then, I add a single phone with id 1 and map them to both the user IDs(1&2) .
My USER_PHONE table looks as below:
Select * from USER_PHONE;
+----------+---------+
| phone_id | user_id |
+----------+---------+
| 1 | 1 |
| 1 | 2 |
+----------+---------+
Now, I wish to remove a user with ID 2.
When I try to do this, I get an error
javax.persistence.PersistenceException: org.hibernate.exception.ConstraintViolationException: Cannot delete or update a parent row: a foreign key constraint fails (`dbname`.`USER_PHONE`, CONSTRAINT `FKC6A847DAFA96A429` FOREIGN KEY (`user_id`) REFERENCES `USER` (`ID`))
My delete script:
String query = "DELETE User where id=?1";
try{
Query q = entityManager.createQuery(query);
q.setParameter(1,id);
q.executeUpdate();
System.out.println(System.currentTimeMillis() + " DELETE: userId " + id + " ==> deleted");
} catch(Exception e){
e.printStackTrace();
return false;
}
Any idea where am I going wrong ?
Thanks a lot :)
Try using entityManager.createNativeQuery(). You cannot use createQuery() because the table should be present as an entity in your Java code. Also, you need to use the exact SQL format.
String query = "DELETE FROM USER_PHONE WHERE user_id=?1";
try{
Query q = entityManager.createNativeQuery(query);
q.setParameter(1,id);
q.executeUpdate();
System.out.println(System.currentTimeMillis() + " DELETE User_Phone: userId " + id + " ==> deleted");
} catch(Exception e){
e.printStackTrace();
return false;
}`
First delete the row from USER_PHONE (using createNativeQuery()), and then from User (using createQuery())
Make the following change.
//User class
#ManyToMany(cascade = {CascadeType.MERGE,CascadeType.REMOVE}, fetch = FetchType.EAGER)
...
private List<Phone> phones;

Two ManyToMany relationships in one JPA entity

I have an entity called User with two many-to-many relationships: User -mtm - Role and User -mtm - Course
public class User {
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "users_roles",
joinColumns = {#JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "role_id", referencedColumnName = "id")})
private List<Role> userRoles;
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(name = "users_courses",
joinColumns = {#JoinColumn(name = "user_id", referencedColumnName = "id")},
inverseJoinColumns = {#JoinColumn(name = "course_id", referencedColumnName = "id")})
private List<Course> orderedCourses;
}
In Course entity:
public class Course {
#ManyToMany(mappedBy = "orderedCourses")
private List<User> participants;
}
It looks similar in the Role entity.
When user with e.g. two roles assigned enrolls himself to some course (means that course is added to his orderedCourses list), he gets this course twice.
So the user with two roles gets registered for the same course twice, user with 3 roles gets it three times etc.
It is noticeable in the junction table in the database. (one user has the same course few times which is unacceptable).
Looks like one ManyToMany relationship has an impact on another. But I don't know what is wrong.
Everything is persisted to MySQL database by Hibernate (via Spring Data JPA)

Data lost when trying to edit record

I'm currently having this issue: I have 3 tables: users, roles and users_roles as in the picture below:
whenever I edit any of the record in users table, the record of that user in the users_roles table will be lost.
For example, I changed the username of the user which holds the userId = 2, then in the users_roles table, the row of userId = 2 will be lost.
Anybody has any ideas of this problem? I'm using Spring with Hibernate
*UPDATE
In my Role.java
#ManyToMany(fetch = FetchType.EAGER, mappedBy = "roles")
private List<User> users;
In my User.java
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
#JoinTable(name = "users_roles", joinColumns = #JoinColumn(name = "userId", nullable = false) , inverseJoinColumns = #JoinColumn(name = "roleId", nullable = false) )
private List<Role> roles;
And in my UsersRoles.java
#Id
#Column(name="userId")
private int userId;
#Id
#Column(name="roleId")
private int roleId;
This is the DAO implementation method I used for Edit
#Override
public void edit(User user) {
session.getCurrentSession().saveOrUpdate(user);
}
P/S: this not only happens when I edit with my web-app, but also happens when I edit directly in MySQL environment. I don't know...

Null not allowed, but should be nullable

I have two tables joining with a mapping table. I am getting a null constraint issue though. Below is the error message and the two mappings. Since both are manyTomany my assumption is that the many could be none, how can I make it so either product_id or category_id can be null?
Error Message
Caused by: org.h2.jdbc.JdbcBatchUpdateException: NULL not allowed for column "PRODUCT_OPTION_ID"; SQL statement:
insert into ImageMapping (product_id, image_id) values (?, ?) [23502-168]
Categories
#JoinTable(
name = "ImageMapping",
joinColumns = #JoinColumn(name = "category_id"),
inverseJoinColumns = #JoinColumn(name = "image_id")
)
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
private Set<Image> categoryImageId;
Products
#JoinTable(
name="ImageMapping",
joinColumns = #JoinColumn(name = "product_id"),
inverseJoinColumns = #JoinColumn(name = "image_id")
)
#ManyToMany(fetch = FetchType.EAGER, cascade = CascadeType.PERSIST)
private Set<Image> productImageGroup;
Product Options
#JoinTable(
name="ImageMapping",
joinColumns = #JoinColumn(name = "product_option_id"),
inverseJoinColumns = #JoinColumn(name = "image_id")
)
#OneToMany(fetch = FetchType.EAGER, cascade = CascadeType.ALL)
private Set<Image> productOptionImageGroup;
You should have a separate join table for each of your associations instead of trying to use the same one for all.