4

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...

Pierre Henry
  • 16,658
  • 22
  • 85
  • 105

1 Answers1

0

You can use a @AttributeOverrides to specify the prefixed column names in the @Entity. But I see no way to declare the prefix only once.

See this question : JPA Multiple Embedded fields

Community
  • 1
  • 1
jps
  • 164
  • 2
  • 8
  • Yes, I also discovered that you can use the @AttributeOverrides on the type, to override the parent class mappings. But that's still 6-7 lines of annotations to each of my entities... – Pierre Henry Sep 03 '13 at 12:08