I am using annotations on the getters/setters because I have an API separated from the implementation, and I wanted to keep the API part completely framework-free, allowing me to switch frameworks or provide different implementations. For instance, right now I'm using spring-data-jpa, but with the API below I can easily switch to spring-jdbc or any other framework.
What I did was define the interfaces for the controller, repository and the entity, as such:
public interface MyEntityController<T extends MyEntity> {
Iterable<T> listEntities();
T getEntity(Long id);
}
public interface MyEntityService<T extends MyEntity> {
Iterable<T> findAll();
T findById(Long id);
}
public interface MyEntityRepository<T extends MyEntity> {
Iterable<T> findAll();
T findOne(Long id);
}
// no JPA annotations here
public abstract class MyEntity {
protected Long id;
protected String myField;
}
Next I just implement the MyEntity as follows, and use the MyEntityImpl for the Controller, Service and Repository implementations:
@Entity
public class MyEntityImpl extends MyEntity {
@Id public long getId() { return id; }
@Column public String getMyField() { return myField };
// setters, etc
}
@Repository
public interface MyEntityRepositoryImpl extends MyEntityRepository, JPARepository<MyEntityImpl, Long> {
}
I have already tested it and it works fine. Just annotating the MyEntityImpl
with @Entity
would not have worked, as the superclass would need to be a @MappedSuperclass
.