I have an existing schema where each table is attributed a 3 letters prefix that is then used on each column. For example :
Table : USER
Prefix : USR
Fields : USR_ID, USR_STATUS, USR_LAN_ID
etc.
The DB guy likes it, he also uses the table prefix in FK fields (Ex. USR_LAN_ID
where LAN
is the LANGUAGE
table's prefix. Says it makes SQL (and PL/SQL) more readable. And I have no influence on this policy.
I can live with it in JPA by explicitly mapping the columns with the @Column
annotation. I'll need it anyway most of the time for additional meta-data (length, nullability etc.).
But then there are about 5 or 6 columns that are common to every table and that I want to regroup in a @MappedSuperclass
. Those fields are : ID
, STATUS
, and auditing fields (creation, update user and date).
But it doesn't work because, although these fields are semantically the same, they are named differently (once is will be USR_ID
, another it will be GRP_ID
etc.)
What strategy could I use to circumvent this problem and still be able to regroup those fields in a common superclass and avoid lots of redondant boilerplate code in all my entities ?
My first idea was to create a custom NamingStrategy
, in conjunction win a custom @TablePrefix
annotation, but it seems it can't work because the naming strategy is just a generic mechanism and is not aware of the table's name or entity class when generating the columns' names.
Is there some other Hibernate class that I could extend ?
Any suggestions ?
I am so far using JPA 2 with Hibernate as my provider. But it is still early in the project and I am potentially open to solutions that would involve a change of provider.
Edit : the "least bad" solution I have found so far is to override the column names on each entity. For example on the Role entity, add this before the class :
@AssociationOverrides( {
@AssociationOverride(name="creationUser", joinColumns=@JoinColumn(name="APR_USR_ID_CREATE")),
@AssociationOverride(name="updateUser", joinColumns=@JoinColumn(name="APR_USR_ID_MODIFY"))
})
@AttributeOverrides({
@AttributeOverride(name = "id", column = @Column(name = "APR_ID")),
@AttributeOverride(name = "status", column = @Column(name = "APR_STATUS")),
@AttributeOverride(name = "creationDate", column = @Column(name = "APR_USR_CREATE_DATE")),
@AttributeOverride(name = "updateDate", column = @Column(name = "APR_USR_MODIFY_DATE"))
})
Better than redefine everything inside the class, but still 10 lines of ugly redondant code for each entity (quite redondant since the only thing that will vary between entities is the 2-letters prefix in tables' names, in this case "APR_".)
One idea that may work : add a custom @TablePrefix annotation, and implement an annotation processor to generate the above stuff at compile time, depending on the base class... a big hammer for a small nail maybe, but if the number of entities is high, it could be worth it...