In a JPA entity hierarchy using InheritanceType.JOINED, all relationships with subclasses result in foreign key constraints in the superclass table

I have the following JPA 2.0 objects

@Entity @Inheritance(strategy= InheritanceType.JOINED) public abstract class BookKeepingParent implements Serializable { @Id protected Long Id; ... } @Entity public class Employee extends BookKeepingParent { private String name; @ManyToOne private Role role; ... } @Entity public class Role extends BookKeepingParent { private String name; ... } 

I want JPA to create tables for me as it simplifies installation in several places. I usually expected this to generate this:

 CREATE TABLE bookkeepingparent ( id bigint NOT NULL, dtype character varying(31), CONSTRAINT bookkeepingparent_pkey PRIMARY KEY (id ) ) CREATE TABLE role ( id bigint NOT NULL, name character varying(255), CONSTRAINT role_pkey PRIMARY KEY (id ), CONSTRAINT fk_role_id FOREIGN KEY (id) REFERENCES bookkeepingparent (id) ) CREATE TABLE employee ( id bigint NOT NULL, name character varying(255), role_id bigint, CONSTRAINT employee_pkey PRIMARY KEY (id ), CONSTRAINT fk_employee_id FOREIGN KEY (id) REFERENCES bookkeepingparent (id), CONSTRAINT fk_employee_role_id FOREIGN KEY (role_id) REFERENCES role (id) ) 

The first two tables, where they are the same, but generated the employee table as follows:

 CREATE TABLE employee ( id bigint NOT NULL, name character varying(255), role_id bigint, CONSTRAINT employee_pkey PRIMARY KEY (id ), CONSTRAINT fk_employee_id FOREIGN KEY (id) REFERENCES bookkeepingparent (id), CONSTRAINT fk_employee_role_id FOREIGN KEY (role_id) REFERENCES bookkeepingparent (id) ) 

You may notice that fk_employee_role_id refers to the bookkeepingparent table instead of the role table. I have a large hierarchy of JPA entities, and I want accounting to be the superclass of most of them. This is primarily due to some very specific strategies for generating identifiers and other types of accounting. This design helps keep the code for this book separate from the functional code and let programmers working on the functional code not have to worry about it.

All this worked well until the number of tables grew. Now we see that for all ManyToOne and OneToOne JPA creates foreign keys related to the parent table. With 200 odd tables, inserts are already slow, because all foreign key constraints apply to the bookekeepingparent element, and each object, when it is stored for the first time, is inserted into the parent accounting table. Which, I think, checks out about 150 odd constraints.

So the following are my questions: why does JPA do this? Is this standard JPA behavior? (I use EclipseLink) If I manually change the database schema, are there any pitfalls to expect?

This is my first question about StackOverflow, I tried my best to look for any existing answers. Sorry if I missed. Thank you

+4
source share
1 answer

You use combined inheritance, which means that for each class the accounting table is the main table, and any subclass table is secondary. The primary key for subclasses is inherited from the parent, and foreign keys must refer to the identifier, so everyone will refer to the identifier in accounting prepared by design. Different vendors allow non-pk fields to be referenced, but this can cause problems, because resolving the links may require database hits instead of using the cache.

Database restrictions are not related to JPA, so you can change them as needed and not affect the application until insert and delete updates are still consistent.

+1
source

Source: https://habr.com/ru/post/1485044/


All Articles