Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Can I "override" annotations of a superclass's private field?

20 years in other programming languages and now I am new to Java, feeling like an noob programmer...

I use an Indexable abstract class to extend all of my @entity classes so I don't need to put the @Id @GeneratedValue @SequenceGenerator on all of them. And I also have Auditable with @CreatedBy @CreatedDate @ModifiedBy @ModifiedDate which leads to those inheritance path:

  • MostEntityClasses > AuditableClass > IndexableClass;
  • SomeEntityClasses > IndexableClass.

Now I noticed that 99% of my entity classes also have:

@Column(nullable = false, unique = true) private String name;

I thought of moving that line to the Indexable class to avoid that boilerplate code in those 99%, but the two classes that don't have the name field are important auditable classes and I don't want to just copy all the ancestor fields to them just to prevent errors of null names on it.

The question is: if I override that field's annotations on those two classes to make it nullable and transient, will it work to avoid creating this field on the table and also not bothering the user with null names?

class SomeAuditableClass extends Audited {
  //@override
  @Column(nullable = true) @Transient private String name;

The content in Is there a way to override class variables in Java? did not helped much...

like image 351
NaN Avatar asked Oct 28 '25 08:10

NaN


2 Answers

While not an answer to your exact question, the typical way of approaching this would be to extend Indexable with another class, say, IndexableWithName. Then, the 99% of your entities that have the name field would extend IndexableWithName, while the two classes that don't have the name field would directly extend Indexable.

I couldn't say without trying it whether what you propose would work as far as the database mapping is concerned. But I think it would be bad class design, as presumably you would have a getter and maybe a setter for the name field in the superclass, and they wouldn't make sense on the two classes that don't really have a name field.

like image 163
Bernie Avatar answered Oct 29 '25 23:10

Bernie


No you can't override them:

  • At the Java language level, there are no annotation overriding mechanisms for fields.
  • Private fields of a parent class are inaccessible in a child class to prevent the child class from breaking / interfering with the abstraction.

At runtime you could potentially break abstraction using reflection to see the annotations a superclasses private fields. But you cannot add or remove them: see Adding Java Annotations at Runtime. And even if you could, runtime may be too late.

The only way that you could get some traction here would be to identify the code that is processing the annotations, and modify it to (somehow!) accept overrides from some (non-java) file.

But for your use-case, that seems like a very bad idea. You don't want to create and maintain a private fork of (say) Hibernate with non-standard functionality just to save you a relatively small amount on boilerplate code.

like image 42
Stephen C Avatar answered Oct 29 '25 21:10

Stephen C



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!