Join table data gets deleted when updating an entity in ManyToMany Relationship - spring

I have this Recipe entity with ManyToMany relationship with Category entity
#ManyToMany
#JoinTable(name = "recipe_category", joinColumns = #JoinColumn(name =
"recipe_id"),
inverseJoinColumns = #JoinColumn(name = "category_id"))
private Set<Category> categories;
The relationship in the Category entity is this.
#ManyToMany(mappedBy = "categories")
private Set<Recipe> recipes;
The Recipe, Category, Recipe_Category gets created along with a bunch of other tables based on other entities. However, when I edit Recipe, the data in the join table Recipe_Category gets deleted.
Why is this behavior and what I need to do to fix it?
Thanks in advance.

Related

How to create join table with extra column with JPA annotations?

I need for a project to join 2 SQL tables implemented like this :
I know that I'm not supposed to implement the table IngredientList as an object cause it's only here for SQL structure.
My code goes like this :
#Entity
#Table(name="recipe")
public class Recipe {
#Id
#GeneratedValue(strategy=GenerationType.AUTO)
#Column(name="id_recipe")
private Long id;
#OneToMany
#JoinTable(name="liste_ingredients", joinColumns = #JoinColumn(name = "id_recette",
referencedColumnName = "id_recette"),
inverseJoinColumns = #JoinColumn(name = "id_ingredient",
referencedColumnName = "id_ingredient"))
List<Ingredient> ingredients;
/* Getter/Setter/Constructor */
}
Which is the classic way but with that I lose the Quantity attribute that I want to associate with ingredient. And I don't get how I can work around this without creating an object IngredientList.
Thanks in advance.
Nevermind that I got my answer gonna edit it soon with code, for anyone with the same question.

AuditorAware is not working for Many-Many relationship

I use Spring data AuditorAware feature to audit CreatedBy,LastModifiedBy,CreatedDate and LastModifiedDate. It perfectly works for all the entities even when an entity is in one-many relationship. But It doesn't work for many-many relation ship.
For Ex,
I have entities user and user_group with many-many relationship. So it has another table user_group_association with user_id and user_group_id
Whenever there is an create or update in usergroup then audit columns get updated in usergroup table. But within the same transaction if any create/update to user_group_association there is no changes for these columns.
As I define many-many relation ship as below, I wouldn't have an entity class for user_group_association
// bi-directional many-to-many association to Users through
// user_group_association
#ManyToMany(fetch = FetchType.LAZY, cascade = { CascadeType.PERSIST, CascadeType.MERGE })
#JoinTable(name = "user_group_association", joinColumns = #JoinColumn(name = "user_group_id"), inverseJoinColumns = #JoinColumn(name = "user_id"))
private Set<User> users;
How can I force Spring Data to make entires in user_group_association table as well ?

How to add a where clause to a Hibernate #ManyToMany relationship?

Given two entities:
PurchaseProductGroup
PurchaseProduct, which has a status column that can be 'A' (active) or 'D' (deleted)
and a many-to-many relationship defined in PurchaseProductGroup:
/** The purchase products linked to this group. */
#ManyToMany
#JoinTable(name = "purchaseprodgrp_purchaseprod",
joinColumns = #JoinColumn(name = "ppg_id"),
inverseJoinColumns = #JoinColumn(name = "ppr_id"))
private List<PurchaseProduct> purchaseProducts;
How can I restrict this so that purchaseProducts with a status of 'D' are excluded?
Things I've tried
Have tried adding the following just below the #ManyToMany annotation but both failed with an "invalid identifier" exception for the column:
#Where(clause = "status <> 'D'")
#WhereJoinTable(clause = "purchaseProduct.status <> 'D'")
Also tried using adding #Where(clause = "status <> 'D'") at the entity level but this doesn't seem to affect the contents of relationship collections - as backed up by this question.
Please try the following code:
#ManyToMany
#JoinTable(name = "purchaseprodgrp_purchaseprod",
joinColumns = #JoinColumn(name = "ppg_id"),
inverseJoinColumns = #JoinColumn(name = "ppr_id"))
#Where(clause = "ppr_status <> 'D'")
private List<PurchaseProduct> purchaseProducts;
This may be similar to something you have tried before, but a critical point to get this working is that ppr_status is the actual column name. Hence the PurchaseProduct entity should have the following:
#Column(name="ppr_status")
public String getStatus() {
return status;
}
If you had named the field ppr_status then the #Column may not be necessary. But based on your comments above we need to tell Hibernate how to map this column.
Reference: Hibernate annotations. #Where vs #WhereJoinTable

Retrieve data over a many-to-many relationship in a Spring/Hibernate project

I am new to development using Spring framework and Hibernate. And I need to know what is the best practice to retrieve data from multiple tables. Here is a simple scenario:
Assuming a many-to-many relationship with these tables: Students(sid, name), Courses(cid, title), Students-Courses(sid,cid)
I don't have a Model/Entity class for Students-Courses. Here is how I handled the relationship in the "Student" Model/Entity class:
#JsonIgnore
#ManyToMany(fetch = FetchType.EAGER)
#JoinTable(
name = "students-courses",
joinColumns = {#JoinColumn(name = "sid", referencedColumnName = "sid")},
inverseJoinColumns = {#JoinColumn(name = "cid", referencedColumnName = "cid")})
So, this class creates both "Students" and "Students-Courses" tables in the database via Hibernate. I also have a separate Model/Entity class for Course.
How can I get the list of all the students including their courses (titles)? I mean multiple records for the students with more than one course
I can create an attribute in the "Student" class like this:
private Set<Course> courses = new HashSet<>();
But it won't be returned back if I use a JpaRepository interface/class like
return studentRepository.findAll();
since it's not a #Column.
Should I write native-SQL code in my class?
Should I create an Immutable Entity class so Hibernate create sort of a database-view object in the data layer?
What is the best practice and how should I do that?

Insert data in intermediate table created by spring

I am using spring with JPA and I have 2 model classes
User
Resources
I have defined many to many relation using -
#ManyToMany(cascade = CascadeType.ALL, fetch = FetchType.LAZY)
#JoinTable(name = "users_resources", joinColumns = #JoinColumn(name = "user_id", referencedColumnName = "id"), inverseJoinColumns = #JoinColumn(name = "resource_id", referencedColumnName = "id"))
This definition has created another table users_resources.
To insert data in users_resources table, the REST api is sending just the User id [primary key] and Resource Id [primary key].
Is there anyway I can insert data into users_resources without fetching full user object and resource object? I wanted to use native query but it seems PersistenceJPAConfig has noway to run native INSERT query.
If you know Id of the object, and you need object reference (without object details) you could use EntityManager.getReference()
User userReference=em.getReference(User.class,userId);
Resource resourceReference=em.getReference(Resource.class,resourceId);
Using references will not exectue any SELECTs from the database.

Resources