JPA: How to automatically generate shadow tables (

2019-04-13 15:33发布

问题:

I'm using EclipseLink's History feature.

As far as I understand there is currently no support for actually creating the shadow table. I'm using JPA 2.1 automated schema generation for all my base tables. Works fine.

Now I'm looking for a way to automate the process of creating the shadow tables. For each base table there should be a shadow table with a few extra columns. Otherwise the shadow table has the exact structure of the table it is shadowing.

I have more than 50 entities in the model and with a bit of many-to-many relations thrown in it all maps to around 55 physical tables. I wouldn't want to maintain DDL create scripts for all the shadow tables.

Right now the project is database agnostic (at least for the usual suspects) and I would like to keep it that way. Being tied to EclipseLink is not a problem so an EclipseLink specific solution is ok.

So, how to create them shadow tables ?

It would be ok to have a sub-class for representing each history table. Say if the base class is Car, then:

@Entity
@Table(name="CAR_HIST")
public class ClassHist extends Car {
   ...
   // some extra audit fields here
}

and with an @Inheritance(strategy=InheritanceType.TABLE_PER_CLASS) annotation on Car it will actually do the job with JPA schema generation. So, almost there with this. Except for many-to-many relationship tables where there's no entity I can get my hands on, so cannot get a shadow table generated for the relationship table.

UPDATE

Turns out using inheritance to create the shadow tables isn't such a great idea. The reason is that JPA JPQL queries are polymorphic. This means that a query like SELECT a FROM Car will actually go into the CAR_HIST table as well because CarHist is just a sub-class of Car. You get the UNION of the SELECT from those tables. Obviously not want I want. The other reason why it is not a great idea is that the sub-class used for history will inherit the primary key of its parent. That is also just plain wrong.

UPDATE 2

I've found there's an RFE for this feature in EclipseLink.