Search code examples
javajpaannotationscode-reusereusability

Is there an efficient way to distribute beans without annotations?


I have some beans that I annotated with JPA to handle persistence mapping.

Here is an example:

import javax.persistence.Id;

public class User{
   @Id
   private String id;

   public String getId(){
       return id;
   }

   public void setId(String id){
       this.id = id;
   }
}

Now I want to use this class in another project where I don't need a dependency on javax.persistence, so I'd rather not include it just for such classes.

So I was thinking of splitting this bean in two classes: one with just fields and accessors and a subclass with JPA annotations on accessors. Like:

public class User{
   private String id;

   public String getId(){
       return id;
   }

   public void setId(String id){
       this.id = id;
   }
}

and

import javax.persistence.Id;

public class UserEntity extends User{

   @Override
   @Id
   public String getId(){
       return super.getId();
   }
}

Unfortunately it seems that putting JPA annotations on accessors is a discouraged practice in most cases and I second that.

Can you suggest any cleaner solutions?


Solution

  • If you insist on using annotations to define your entity mappings, then your entity classes cannot avoid being dependent on JPA. If you must present non-JPA-dependent classes representing the same data, and if you want to be able to handle the different representations polymorphically, then your options are limited:

    • the annotated class may extend the non-annotated one, or
    • the annotated and non-annotated classes may extend a common superclass, or
    • the annotated and non-annotated classes may implement a common interface.

    In any of those cases, the entity class can provide its own, annotated, member variables for the entity properties, but in all cases, doing so means the two classes provide separate storage for the entity properties. That's a bit wasteful in the first alternative and possibly in the second, but it's the only way you can annotate the member variables without tying the whole hierarchy to JPA.

    If you want to go in this general direction then I'd recommend using interfaces instead of class inheritance, whether you annotate member variables or accessor methods. Using interfaces for polymorphism better models the reality you describe (some Users are entities but others are not), it does not interfere with any inheritance hierarchy you may want, and if you annotate member variables then it avoids duplicative storage .