Spring JPA ManyToOne relatsionship creates hashed foreign keys - spring

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;

Related

#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

Prevent Hibernate from generating duplicate foreign keys on table?

Our site uses Spring (5.2.8.RELEASE), Hibernate (5.4.19.Final), Tomcat (8.5.x), and SQL Server (2014). Recently, we noticed that the performance is bad in case of deleting a simple record. We found out that it is caused by duplicate foreign keys that were generated by Hibernate. When there is a new table or field, we let Hibernate generate needed new tables or keys (primary key or foreign key) by setting
hibernate.hbm2ddl.auto=update
This is only a one-time deal. After generating new tables or new keys, we prohibit Hibernate from updating any tables or keys by setting
hibernate.hbm2ddl.auto=none
However, hibernate.hbm2ddl.auto=update generates duplicate foreign keys on existing tables. For example, the site allows people to leave comments and upvote/downvote comments. Upvote/downvote table has references to Comment and Account tables, recording which comment was upvoted/downvoted and who did the vote.
Here is the code about the relationship between Vote and Account in Java. In CommentVote.java
#ManyToOne(fetch = FetchType.LAZY)
#JoinColumn(name = "account")
private Account account;
In Account.java:
#OneToMany(mappedBy = "account", targetEntity = CommentVote.class,
fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true)
private List<CommentVote> commentVotes;
Here is what is shown in SQL Management Studio:
In the above picture, foreign key FK17o46... and FKmgsaf... are duplicates. For example, the foreign keys on the Account field:
If we delete the two duplicate keys and set hibernate.hbm2ddl.auto=update, then the they will be generated again. How can we prevent Hibernate from generating duplicate foreign keys if they already exist on tables while still letting it generating keys only for NEW tables or NEW fields?

I am using Spring boot jpa with Restful api services to insert multiple users in array or list

As I am new to Spring boot. I am not at all clear about mappings. By using #Onetomany mapping in one entity and #manytoOne mapping at other entities. Using the controller I have to write REST API functions to insert multiple users at a time inside an array or set. Can anyone please suggest some websites or provide some existing codes?
The #OneToMany and #ManyToOne mappings can be used according to your use-case, whether you need bi-directional mappping or not. For a simple example consider the following :
#Entity
#Table(name="ENTITY_A")
public class EntityA{
//...
#OneToMany(mappedBy="EntityA")
private Set<EntityB> entityBItems;
// getters and setters
}
#Entity
#Table(name="ENTITY_B")
public class EntityB{
//...
#ManyToOne
#JoinColumn(name="entityA_id", nullable=false)
private EntityA entityA;
public EntityB() {}
// getters and setters
}
What you need to look out for is the owning side of the relation indicated by the mappedBy . The owning entity can be used to persist and get the data from the database. But from the description in your question I cannot understand whether you actually need to use mappings at all as you just have to insert multiple users into a table without any relations to another entity. It will be more helpful if you could explain more about your use case and provide code samples for furthur analysis.
For details about the mappings article or article .
Official doc .
MappedBy signals hibernate that the owner of key (relationship) is on the other side.
This means that although you link 2 tables together, only 1 of those tables has a foreign key constraint to the other one.
MappedBy allows you to still link from the table not containing the constraint to the other table.
If you still want use #JoinColumn on both the Entities you can use #JsonManagedReference and #JsonBackReference from com.fasterxml.jackson
To save the multiple records at same time you can use yourRepository.saveAll(entities)

Postgresql and Spring Roo Binding serial type for ID

I am having trouble using the Postgresql serial type in Spring Roo. What I want is to have the an auto-incrementing id column which will work with the auto generated entity classes in Roo.
The Postgresql sequences, which are generated with the default way of doing things in Spring Roo, work fine within the spring application. But sometimes I have to manually insert rows in the database using sql. (the sequences dont seem to work properly when I do an INSERT INTO... statement). If I could use serial type, then manual INSERTS are easy.
For example I have an office entity and and employee entity. There is a many-to-one relationship between employees and offices.
Here is my class for the Office entity.
#RooJavaBean
#RooToString
#RooJpaActiveRecord
public class Office {
#Id
#Column(name="officeid", columnDefinition = "serial")
#Generated(GenerationTime.INSERT)
#GeneratedValue(strategy = GenerationType.IDENTITY)
private Long officeid;
/**
* Office Name
*/
#NotNull
#Size(max = 100)
private String name;
}
While this does work when my test inserts an office record, it fails when an employee record is inserted since the officeid foreign key value is null. (I guess it needs to flush between the office insert and the employee insert, but the auto-generate tests dont seem to do that.)
So what is the proper annotations to use to tell Roo (and hibernate/jpa) to use the serial data type, and also to work properly with inserts and relationships within the spring application?
Roo generates default JPA annotations, you must customize and setup them as needed. Note Roo guarantees your changes won't be modified.

Hibernate Mysql mapping relationship

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.

Resources