I'm using the javax.persistence
package to map my Java classes.
I have entities like these:
public class UserEntity extends IdEntity {
}
which extends a mapped superclass named IdEntity
:
@MappedSuperclass
public class IdEntity extends VersionEntity {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private Integer id;
// Getters and setters below...
}
The IdEntity
super class extends another mapped super class named VersionEntity
to make all entities inherit version properties:
@MappedSuperclass
public abstract class VersionEntity {
@Version
private Integer version;
// Getters and setters below...
}
Why?
Because now I can make generic queries on the IdEntity class for all entities, and it will look like this: (example)
CriteriaBuilder builder = JPA.em().getCriteriaBuilder();
CriteriaQuery<IdEntity> criteria = builder.createQuery(IdEntity.class);
Now to the problem.
Some of my entities will have timestamps like created_at
and deleted_at
. But not all entities.
I could provide these properties in my entity classes like this:
public class UserEntity extends IdEntity {
@Basic(optional = false)
@Column(name = "updated_at")
@Temporal(TemporalType.TIMESTAMP)
private Date updatedAt;
}
But as I have a lot of entities, this will make me put a lot of redundant code in all entities that should have timestamps. I wish there was some way I could make the relevant classes inherit these fields in some way.
One possible solution is to create a parallell IdEntity
superclass, maybe named IdAndTimeStampEntity
and make those entities that should have timestamps inherit from this new superclass instead, but hey that's not fair to my colleague-developers because now they have to know which super class to choose from when writing generic queries:
CriteriaBuilder builder = JPA.em().getCriteriaBuilder();
CriteriaQuery<???> criteria = builder.createQuery(???); // Hmm which entity should I choose IdEntity or IdAndTimeStampEntity ?? *Annoyed*
And the generic entity queries become not so generic..
My question: How can I make
all
of my entities inheritid
andversion
fields, but only a sub part of all entities inherit timestamp fields, but keep my queries to a single type of entities?
Update #1
Question from Bolzano: "can you add the code which you specify the path(holds table info) for entities ?"
Here is a working example of querying a UserEntity
which is a IdEntity
CriteriaBuilder builder = JPA.em().getCriteriaBuilder();
CriteriaQuery<IdEntity> criteria = builder.createQuery(IdEntity.class);
Root<IdEntity> from = criteria.from(IdEntity.class);
criteria.select(from);
Path<Integer> idPath = from.get(UserEntity_.id); //generated meta model
criteria.where(builder.in(idPath).value(id));
TypedQuery<IdEntity> query = JPA.em().createQuery(criteria);
return query.getSingleResult();
IdAndTimeStampEntity
and making it a child ofIdEntity
? This way queries forIdEntity
will also work on the timestamped version. – Modifyquery.getSingleResult()
going to return an instance of justIdEntity
, so the only thing accessible is id and version? If the caller wants any other column information from the entity they have to cast it (and know what type to cast it to). This seems like a very narrowly useful feature; and one that could easily be hidden behind a generic helper method rather than a solution that dictates your entire object hierarchy. – VidetteMappedSuperclass
s as a target of queries. – Ecclesiology