How to create a simple connection table in Java? - java

I am trying to set up a very simple database with two tables in Java and connect them using a specific connection table.
1st table Student consists of id, first_name and last_name.
2nd table Course consists of id and name.
The connection table called Enrollment should have course_id and student_id that originate from 1st and 2nd tables.
My problem is I don't know how to map the IDs when extending Spring Data JPA's AbstractPersistable, which has an auto-increment primary key field in it.
My code:
Student:
// Package
// Imports
#Entity
#Data #NoArgsConstructor #AllArgsConstructor
public class Student extends AbstractPersistable<Long> {
private String first_name;
private String last_name;
}
Course:
// Package
// Imports
#Entity
#Data #NoArgsConstructor #AllArgsConstructor
public class Course extends AbstractPersistable<Long> {
private String name;
}
I have tried different usages of #ManyToMany annotation but since the primary key ID is handled by AbstractPersistable, I have failed to map the 'invisible' IDs for the connection table.
I also know that the connection table and its columns can be named with #Column, #JoinColumn and #JoinTable. I haven't gotten that far yet.

Hi i would try something like this ...
#Entity
#Data #NoArgsConstructor #AllArgsConstructor
public class Student extends AbstractPersistable<Long> {
private String first_name;
private String last_name;
#ManyToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
})
#JoinTable(name = "enrollment",
joinColumns = #JoinColumn(name = "student_id"),
inverseJoinColumns = #JoinColumn(name = "course_id")
)
private List<Course> courses;
}
#Entity
#Data #NoArgsConstructor #AllArgsConstructor
public class Course extends AbstractPersistable<Long> {
private String name;
#ManyToMany(mappedBy = "courses")
private List<Student> students;
}

Related

Extra association table is created in spring boot

I'm currently working on developing a recipe application and I'm having trouble with DB table generation.
Here are the Entity files I'm using:
// Recipe.java
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "recipes")
public class Recipe {
#Id
#GeneratedValue
private int id;
private String name;
private String description;
private String instruction;
#ManyToOne
private User user;
#OneToMany(cascade=CascadeType.ALL)
private List<RecipeIngredient> ingredients = new ArrayList<>();
}
// Ingredient.java
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Table(name = "ingredients")
public class Ingredient {
#Id
#GeneratedValue
private int id;
private String name;
}
// RecipeIngredient.java
#Data
#Entity
#AllArgsConstructor
#NoArgsConstructor
public class RecipeIngredient {
#Id
#GeneratedValue
private int id;
#ManyToOne
private Ingredient ingredient;
private String amount;
}
Spring Boot Automatically creates tables for me but I just wanna have one table for RecipeIngredient, but it creates two tables for them.
It works perfectly fine but the thing I want is just how to make these two tables into one or make spring boot not generate one of them.
If you want recipe_ingedients table only delete recipeIngredient Entity Class and if you want to keep recipe_ingredient table remove this:
#OneToMany(cascade=CascadeType.ALL)
private List<RecipeIngredient> ingredients = new ArrayList<>();

JPA mappedBy reference an unknown target entity property

Hello I am new to JPA Spring boot and right now I am trying to make a connection between two tables into a third one. So I have a Doctor and Patient table with it's properties, where one Doctor can examine every patient and a patient can visit every doctor.But in one examination there can be no more than one patient and one doctor. For the doctors I want to keep the information of which patients they have examined, respectively for the patients, which doctors they were examined from. I would like to create a middle table called DoctorVisit where I have the id of the doctor who did the examination and the id of the patient with some more properties like date,medicines and etc. When I try to do this I am getting an error - "mappedBy reference an unknown target entity property: /.../Patient.examinedByDoctors". If I remove the #OneToMany connection in Patient the code compiles. I would be really happy if someone can explain me where is the mistake. Thank you in advance
BaseEntity class:
#Getter
#Setter
#NoArgsConstructor
#MappedSuperclass
public class BaseEntity {
#Id
#GeneratedValue(strategy= GenerationType.IDENTITY)
private long id;
}
Doctor class:
#Getter
#Setter
#NoArgsConstructor
#Entity
#Table(name="doctor")
public class Doctor extends BaseEntity{
private String name;
#ManyToMany(mappedBy ="doctors")
private Set<Specialty> specialties;
#OneToMany(mappedBy ="doctor")
private Set<Patient> GpOfPatients;
#OneToMany(mappedBy = "doctor")
private List<Patient> examinedPatients;
}
Patient class:
#Getter
#Setter
#NoArgsConstructor
#Entity
#Table(name="patient")
public class Patient extends BaseEntity{
private String name;
private String EGN;
private boolean insurancesPaidInLastSixMonths;
#ManyToOne
#JoinColumn(name="gp_id")
private Doctor doctor;
#OneToMany(mappedBy = "patient")
private List<Doctor> examinedByDoctors;
}
Specialty class:
#Getter
#Setter
#NoArgsConstructor
#Entity
#Table(name="specialty")
public class Specialty extends BaseEntity{
private String specialtyName;
#ManyToMany
#JoinTable(name="doctors_specialties",joinColumns = #JoinColumn(name="specialty_id"),
inverseJoinColumns = #JoinColumn(name="doctor_id"))
private Set<Doctor> doctors;
}
DoctorVisit class:
#Getter
#Setter
#NoArgsConstructor
#Entity
#Table(name="doctorvisit")
public class DoctorVisit extends BaseEntity {
#ManyToOne
#JoinColumn(name = "patient_id")
private Patient patient;
#ManyToOne
#JoinColumn(name="doctor_id")
private Doctor doctor;
private Date date;
private String diagonosis;
#ManyToMany(mappedBy = "prescribedToPatients")
private Set<Medicine> medicines;
private int patientChart;
}
Medicine class:
#Getter
#Setter
#Entity
#Table(name = "medicine")
public class Medicine extends BaseEntity{
private String name;
private String manufacturer;
#ManyToMany
#JoinTable(name="prescribedMedicines_to_patients",joinColumns = #JoinColumn(name="medicine_id"),
inverseJoinColumns = #JoinColumn(name="patient_id"))
private List<Patient> prescribedToPatients;
}
You get this error because the Doctor class does not have a patient field. However adding a Patient won't fit your use case, because a Doctor can have multiple Patients not just one. So you have to create a ManyToMany association between Patient and Doctor or use only the DoctorVisit to connect the two entities. I would apply the second option and use special queries to get who visited who with the DISTINCT keyword for example.

Java Repository Query findAll() given an ID from another class (Foreign-Key)

I'm using a JPARepository called PublicationRepository and want to find all Publications from a certain Person. This Classes are connected over the Class Author.
Person Class:
#Entity
public class Person {
#Id
private String email;
private String telefon;
private String password;
#OneToMany(mappedBy = "person")
Set<Author> Author;
}
Author Class:
#Entity
#Data
#NoArgsConstructor
#AllArgsConstructor
public class Author {
#Id
private int id;
#ManyToOne
#JoinColumn(name="Person_ID")
Person person;
#ManyToOne
#JoinColumn(name="Publication_ID")
Publication publication;
private String Date;
private String Writerstatus;
}
Publication Class
#Entity
#AllArgsConstructor
#NoArgsConstructor
#Data
public class Publication {
#Id
private int id;
private String publicationname;
#OneToMany(mappedBy = "publication")
Set<Author> author;
}
And the PublicationRepository
public interface ProjektRepository extends JpaRepository<Projekt,Integer> {
}
public interface PublicationRepository extends JpaRepository<Publication,Integer> {
#Query(value = "SELECT pub.* FROM author as auth INNER JOIN publications as pub ON auth.publication_id = pub.id WHERE auth.person_id = ?1", native = true)
List<Publication> findAllPublicationsOfThisPerson(int personId);
}
Try this.
I would also recommend to annotate the entities with their table names:
#Table(name = "publication")
You use a manually build table for a Many-to-Many relationship Author
You could also delegate that to Spring Data Jpa by using #ManyToMany Annotation.
A good tutorial:
https://attacomsian.com/blog/spring-data-jpa-many-to-many-mapping

#ManyToMany java spring boot

This is STUDENTS ENTITY
#Entity
#Table(name = "STUDENTS")
public class Student extends BaseEntity {
#Column(name = "student_index")
public String index;
public String firstName;
public String lastName;
#ManyToMany
public List<Course> courses;
}
This is COURSES ENTITY
#Entity
#Table(name = "COURSES")
public class Course extends BaseEntity {
public String name;
#ManyToMany
public List<Student> students;
}
Which tables will be generated in DataBase?
There must be tables
STUDENTS, COURSES, STUDENTS_COURSES, COURSES_STUDENTS
The #ManyToMany will be confused and will create two tables STUDENTS_COURSES, COURSES_STUDENTS
To avoid such situation need to provide option mappedBy
ie.
#ManyToMany(mappedBy = "STUDENTS")
it will create only one table STUDENTS_COURSES

Hibernate inheritance - OneToMany with 2 class that extend parent not work

I have 3 Entities:
#Data
#AllArgsConstructor
#Entity
#Table(name = "beneficiary")
#Inheritance
#DiscriminatorColumn(discriminatorType = DiscriminatorType.STRING, name = "type")
public abstract class Beneficiary {
public Beneficiary() {}
#Id private String id;
private String description;
}
#Data
#Entity
#DiscriminatorValue("company")
#EqualsAndHashCode(callSuper = true)
public class BeneficiaryCompany extends Beneficiary {
public BeneficiaryCompany() {
super();
}
public BeneficiaryCompany(String id, String description) {
super(id, description);
}
}
#Data
#Entity
#DiscriminatorValue("person")
#EqualsAndHashCode(callSuper = true)
public class BeneficiaryPerson extends Beneficiary {
public BeneficiaryPerson() {}
public BeneficiaryPerson(String id, String description) {
super(id, description);
}
}
An in the other class I want to have 2 separate collections:
#Data
#AllArgsConstructor
#Entity
#Table(name = "transaction")
public class Transaction {
public Transaction() {}
#Id private String id;
private String description;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true, targetEntity = BeneficiaryCompany.class)
#JoinColumn(name = "transaction_id", nullable = false)
private Set<BeneficiaryCompany> beneficiaryCompanies;
#OneToMany(cascade = CascadeType.ALL, orphanRemoval = true,targetEntity = BeneficiaryPerson.class)
#JoinColumn(name = "transaction_id", nullable = false)
private Set<BeneficiaryPerson> beneficiaryPeople;
}
The problem is that every Beneficiary was fetched into beneficiaryCompanies, and beneficiaryPeople in the debugger tells me that:
Unable to evaluate the expression Method threw
'org.hibernate.WrongClassException' exception.
The database records looks fine (DiscriminatorColumn was created). What could be the problem? Why beneficiaryCompanies contains BeneficiaryPerson objects?
#EDIT:
To fetch the records I am using SpringData JPA repositories.
Use #MappedSuperclass on your base class Beneficiary
Alexandar Petrov is absolutely correct. You have to remove #Entity because superclass is not an entity. When dealing with inheritance extending a class, you can use #MappedSuperclass annotation on the base class, in your case, it is Beneficiary.
Edit:
This is a very good article you can refer to.

Categories