Which entity class in Spring Boot should have cascade functionality? - spring-boot

I have an Employee entity class which has a one to many relationship with Skills entity class.
Should we specify cascade in Employee class or in Skills class to achieve the below mentioned conditions
An entry in employee might not have an entry in skills
An entry in employee might have multiple entries in skills
If we delete employee then the corresponding skills of the employee should also be deleted

Map entities like below will fulfill the requirements.
In Employee entity :
#OneToMany(mappedBy="employee",cascade = CascadeType.ALL,fetch=FetchType.LAZY)
private Set<Skill> skills;
In Skill Entity :
#ManyToOne
private Employee employee;
An entry in employee might have multiple entries in skills -- #OneToMany will do this.
If we delete employee then the corresponding skills of the employee should also be deleted --- cascade all will do this.

Related

Many to one mapping Hibernate

I am doing many to one mapping in hibernate. I am using the existing tables which I created earlier for one to many mapping (customer and order) but when I am trying to map and update those table I couldn't able to I don't know how should I processed? and I would like to insert the data meaning I would like to create some more orders using command line runner for that customer.
Could you please help me with this
Appreciate your help.
Mapping one-to-many and many-to-one association
Both associations are the same association seen from the perspective of the owing and subordinate entities and respectively.
Student one-to-many Address
Address many-to-one Student
#OneToMany annotation can be applied to a field or property value of "one" end entity class for a collection or an array representing the mapped "many" end of the association.
#ManyToONe relationship between two entities is by managing the FK(Foreign key) of the "one" end entity, as a column in the "many" entity table.
> **Bidirectional one-to-many using ```#JoinColumn```**
#Entity
public class Student{
#OneToMany(cascade = CasecadeType.ALL)
#JoinTable(name="Student_FK")
public set<Address> getAddress(){
return address;
}
}
One-to-Many side as the owing side, You have to remove the mappedBy element and set the #ManyToOne #JoinColumn as insertable and updatable to false. This Solution is not optimized and will produce some additional UPDATE Statement.
#Entity
public class Address{
#ManyToOne(cascade = CasecadeType.ALL)
#JoinColumn(name="STUDENT_FK", insertable = false, updatable = false)
public Student student;
}
For more details look at this link Link

Use 1 Child entity for 2 parent entities

model
Phone numbers is a common entity for both the Student and employee . How to share the phonenumbers as common Child entity to both the Student and Employee.
What you want to do is create a one-to-many relationship between Student and PhoneNumbers and another one-to-many relationship between Employee and PhoneNumbers. In order to do this you can use the annotations #OneToMany and #JoinColumn. Here's how the code for Employee would look:
#Entity
#Table(name="employees")
public class Employee {
...
#OneToMany
#JoinColumn(name="phone_number_id")
private List<PhoneNumber> phoneNumbers;
...
}
This is an example for unidirectional association, there is also a bidirectional one. For more detailed explanation of both associations you can check out this article.

Must I create a mapping relationship between two entities in hibernate?

For example, if you have an order table in Hibernate and a product table that receives an order, it is mapped as a one to many relationship.Then,Must I write the mapping relationship in code here? In my project, I permanently store order information in a database I have, but in that case, does it need to be a mapping relationship?There's nothing else to do except delete cascade i think.
If you want to use the association in your business code, you also need to model in your domain model. In the described example, I would expect a many-to-many association between the Order and the Product entity. You could model it as a uni- (= only on 1 entity) or bidirectional (= on both entities) association.
Here is a quick example. I provide a very detailed description of all kinds of associations in my guide to association mappings.
public class Order {
#ManyToMany
private Set<Product> products;
...
}
public class Product {
#ManyToMany(mappedBy = "products")
private Set<Order> orders;
...
}

How to establish foreign key relationship with a non entity table in the database using Spring data JPA?

My spring boot project uses an existing database, I have a new model entity/table in my project that must have a foreign key constraint with an existing table in the database.
I've tried to find solution online but all the answers are for the case where both the tables are present as entities in that project and using some #ManyToOne, #OneToMany annotations.
I can't define those annotations because I don't have the reference table as an entity or model in my project.
Let's say I have class like:
#Entity(name = "user")
public class User {
#Id
#GeneratedValue
private long userId;
private long departmentId;
I want to put a foreign key contraint on the departmentId column to reference to id column of the existing department table that isn't defined as a model or entity in my project.
Thanks
Just do it as normal
example
#Column(name = "department_id")
private Department departmentId;
You can later access it Department.departmentId. Hope this helps.
Try it like this
#ManyToOne
#JoinColumn(name="(column name of current entity)", referencedColumnName="(column name in target entity)")
private Department departmentId;
you can skip the referencedColumnName if the column name is same in both the entities

Spring Data Repository query hook

In Spring Data is it possible to extend a query that is generated by the find* functions of the repo interfaces?
Given following use case:
My legacy database has an inheritance by table. So given following
#Entity public class Person {
private int id;
private String className;
}
#Entity #PrimaryKeyJoinColumn(name="id") public class Musician extends Person {
String instrument;
}
#Entity #PrimaryKeyJoinColumn(name="id") public class Lawyer extends Person {
String discipline;
}
My repository for Musician:
public interface MusicianRepository extends CrudRepository<Musician, int> {
List<Musician> findAll();
}
Now an entry for a new musician in SQL would be:
insert into Person(id, className) values(1, 'Musician');
insert into Musician(id, instrument) values(1, 'piano');
When a Musician got migrated to a lawyer the old system added one row to Lawyer table without removing Musician by:
insert into Lawyer(id, discipline), values(1, 'finance');
update Person set ClassName = 'Lawyer' where ID = 1;
My MusicianRepo would now find the lawyer since the row in Musician still exists.
I would need some kind of post processor where I could extend the query by adding a where clause with "ClassName = 'Musician'" on all find* methods.
Is this possible somehow?
I think that your JPA mapping is just not correct in terms of inheritance.
I think you want to have "Joined, Multiple Table Inheritance"
Citing from here:
Joined inheritance is the most logical inheritance solution because it
mirrors the object model in the data model. In joined inheritance a
table is defined for each class in the inheritance hierarchy to store
only the local attributes of that class. Each table in the hierarchy
must also store the object's id (primary key), which is only defined
in the root class. All classes in the hierarchy must share the same id
attribute. A discriminator column is used to determine which class the
particular row belongs to, each class in the hierarchy defines its own
unique discriminator value.
Some JPA providers support joined inheritance with or without a
discriminator column, some required the discriminator column, and some
do not support the discriminator column. So joined inheritance does
not seem to be fully standardized yet.
The className column in Person would be your descriminator column. It determines the subclass to instantiate.
Your mapping would be something like this:
#Entity
#Inheritance(strategy=InheritanceType.JOINED)
#DiscriminatorColumn(name="className")
public class Person {
private int id;
private String className;
}
#Entity
#DiscriminatorValue("Musician")
public class Musician extends Person {
String instrument;
}
#Entity
#DiscriminatorValue("Lawyer")
public class Lawyer extends Person {
String discipline;
}
This way if you query for Lawyer entities JPA would automatically add the where clause to just read rows with className=Lawyer
I did not try the mapping - it should just illustrate the way you should be going.

Resources