Hibernate Mysql mapping relationship - spring

I'm not sure if this is possible to do in Spring 3 framework using hibernate and mysql but I would appreciate any help. I have two classes - Employee and Examiner. The examiner is an employee and an employee is also an examiner. At the same time each Examiner can examine one or more employees and an employee can only have one Examiner.
Basically what I want to know is if it is possible to show the inheritance between the Employee and Examiner, and at the same time map a unidirectional one to many from Examiner to Employee?
What I have so far - the Examiner table with the inheritance constraint:
CREATE TABLE `examiner` (
`employee_id` varchar(255) NOT NULL,
`employee_name` varchar(255) NOT NULL,
PRIMARY KEY (`enployee_id`),
FOREIGN KEY (`employee_id`) REFERENCES `employee` (`employee_id`)):
The employee table:
CREATE TABLE `employee` (
`employee_id` varchar(255) NOT NULL,
`employee_name` varchar(255) DEFAULT NULL,
PRIMARY KEY (`employee_id`)):
I was thinking of a join table for showing the one to many behaviour but getting a compsite key for the table is not possible as I have a primarykeyjoin column.
I would appreciate any help in pulling this together as I have been stumped for days.

Java doesn't allow multiple inheritance, so unless you are using an interface I am not sure how you plan to make the two described classes instances of each other.
You could just make a class called EmployeeExaminer, and make it reference itself. With annotations it might look something like:
#Entity
public class EmployeeExaminer {
#ManyToOne
private EmployeeExaminer getExaminer() {/*...*/}
#OneToMany
private List<EmployeeExaminer> getEmployees() { /*...*/}
}
Documentation on the annotations can be found here.

Thanks #CodeChimp for your replies. I ended up following the first suggestion, and created a Self Reference class with the #onetomany and #manytoone annotations. The helper class for it works. I just have some problems implementing a controller and jsp page for adding the parent/child. But I will make a new question for that. Thanks again.

Related

Spring Boot JPA - Entities

Hopefully, you can help me with the following doubts that I have.
So I have an entity called User that has some columns like Nationality, Gender, Professional Status. And I have an entity for each column referred.
I'm looking for the best way to define this.
Should I apply a ManyToMany relationship between those tables? Since Users can have the same Nationality and Gender?
When I try to implement this, Spring is creating a third table automatically and I don't understand the need.
Having the following shouldn't be enough?:
Table User:
id,
name,
id_nationality.
id_gender,
id_professional_status
Table Nationality:
id,
nationality
(etc)
Why Spring is creating another table called user_nationality?
Thanks in advance.
Whenever we are using the ManyToMany relationship in that case a separate table will be created containing both primary keys of the tables involved in the new relationship.

#JoinColumn and how it links two tables

I am completely new to working with databases and a beginner to Spring Boot as well really so apologies for any wrong terminology/fuzzy logic. There are some similar questions to this on here but I have not found exactly the answer to what I was looking for so I decided to post. Ramble over.
I am reading an article about joining tables in Spring Boot. They have a teacher class and a course class and it is a one-to-many relationship. They don't have the full classes written out but it says that you can go into Teacher class and do:
#OneToMany
#JoinColumn(name = "TEACHER_ID", referencedColumnName = "ID")
private List<Course> courses;
or go to Course class and do:
#ManyToOne
#JoinColumn(name = "TEACHER_ID", referencedColumnName = "ID")
private Teacher teacher;
What threw me off is that the parameters given to JoinColumn were the same in both cases. Assuming that both tables have something called ID, how does Spring know which one to use? Does it start by looking at both tables, looking for teacher_id. Then, after finding that it switches to the other table to get the ID?
Actually this is in the methodology of One-To-Many mappings in relational databases.
To achieve 1-N relation you only need to have:
Table One -> primary_key
Table Many -> primary_key, fk_one_primary_key
With the above configuration, given a table One entity, you can get all it's Many relations using the primaryKey-foreignKey join, and vice versa.
Now, in the code you've shared, the two parameters are described as:
ID -> Primary key column of table One / Teacher
TEACHED_ID -> foreign key column of table Many / Course

Why an #ManyToMany should caused a NullPointerException?

I know that it could be too much vague but what could cause a NullPointerException after adding a #ManyToMany in my jpa entities?
All code is the same, I deleted only the entity linked to the croos table and modified the two entities that before were linked to that entity adding #ManyToMany so the problem isn't the external code or in the db.
The two entities are also linked with a #OneToMany with a second field. Could be this the problem?
This is a structure of my database:
table1: id, name, description and table2_id;
table2: id, name and description;
cross_table: id, table1_id, table2_id and timestamp
Could be a problem the two Set into the entity Table2?
My specs are:
java8
hibernate5.2
jpa2.1
As usual, for me, the message caused a misterunderstanding, I thought the problem was #ManyToMany instead the problem was a my error in hibernate.cfg because I removed only the entity table1_table2 and not the mapping annotation on hibernate.cfg!
Thank you #holi-java for your hint!

Spring JPA ManyToOne relatsionship creates hashed foreign keys

In my entity, I have defined a #ManyToOne(optional = false, cascade = CascadeType.PERSIST) to my other entity. The relationship works fine.
Now I am using Postgre DB where I have created my tables and defined foreign keys between columns in my tables. In my DB, those keys work. When I use my Spring Boot application with it, Spring for some reason creates hashed foreign keys (fk1sishw42l6qx85h5f3pckl6d0) instead using the ones that I have created. At least I think, it uses those.
Why is that so?
How to avoid that?
Hope this solution works, as it worked for me.
#ManyToOne
#JoinColumn(name="employeeID")
#ForeignKey(name='your_existing_constraint_name')
private employee employee;

How to use #SecondaryTable with CrudRepository?

I'm using SecondaryTable to map bean schema to multiple tables:
#Entity
#Table(name = "address1")
#SecondaryTables({
#SecondaryTable(name="address2")
})
How an I then tell spring to create a Repository that uses the values from table address2?
interface AddressRepository extends CrudRepository<Address, Long> {
//this one uses address1
}
I then want to be able to query only the secondary table by the CrudRepository. But how can I explicit tell spring to query the address2 table using the AddressRepository above?
(think of address2-table as a kind of archive table. Only if the address is not found in the primary address1-table, then address2 should be queried).
You can represent two tables which are store different but related data in one entity by using SecondaryTable like user and user_address tables. What You are trying is storing same data in two different tables whhich are identically same. Therefore, SecondaryTable doesn't fit your needs. You should use inheritance annotation with strategy table per class. Here is an example;
#Entity
#Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public abstract class AddressBase {
...
...
...
}
#Entity
#Table(name='address1')
public class Address1 extends AddressBase {}
#Entity
#Table(name='address2')
public class Address2 extends AddressBase {}
Then, you can write repository for each entity and do whatever you want.
I think you are misunderstanding what #SecondaryTable is for. It is a way to split a single entity among different database tables.
From the docs (http://docs.oracle.com/javaee/7/api/javax/persistence/SecondaryTable.html)
Specifies a secondary table for the annotated entity class. Specifying
one or more secondary tables indicates that the data for the entity
class is stored across multiple tables. If no SecondaryTable
annotation is specified, it is assumed that all persistent fields or
properties of the entity are mapped to the primary table. If no
primary key join columns are specified, the join columns are assumed
to reference the primary key columns of the primary table, and have
the same names and types as the referenced primary key columns of the
primary table.
Your annotations, in their current state, say that there exists an Address entity, with data in the address1 and address2 table, which can be combined by joining on the primary key of the address1 table.
I think for what you want to do, and have it work without overriding your CrudRepository, is to just use different tables. You will need to query both tables anyway if I am understanding you correctly.

Resources