JPA Entity With Abstract Class Inheritance
You have several possibilities here.
You did not define a mapping for your superclass. If it is supposed to be a queryable type, you should annotate it with @Entity
and you would also need an @Id
attribute (this missing @Id
attribute is the reason for the error you are getting after adding the @Entity
annotation)
If you do not need the abstract superclass to be a queryable entity, but would like to have it's attributes as columns in tables of it's subclasses, you need to annotate it with @MappedSuperclass
If you do not annotate your superclass at all, it is considered to be transient by the provider and is not mapped at all.
EDIT: By the way, you do not have to modify the lastModified
value yourself (except you really want to) - you can let the persistence provider do it for you each time you persist the entity with a lifecycle callback:
@PreUpdate
void updateModificationTimestamp() {
lastModified = System.currentTimeMillis();
}
Dobbo
I am a long time developer. I have programmed a most levels in the application stack from device drivers to GUIs. I love it all. Getting a computer to do stuff it what gets me out of bed on a cold and damp Monday morning, and as I live in England I know about cold and damp Monday mornings!
Updated on August 15, 2022Comments
-
Dobbo over 1 year
I have an abstract class that provides some common functionality that some of the EJB entities which to inherit. One of these is a timestamp column.
public abstract class AbstractEntity { ... private long lastModified; ... @Column public long getLastModified() { return lastModified; } public void setLastModified(long ts) { lastModified = ts; } }
and
@Table @Entity public class MyEntity extends AbstractEntity { ... private Long key; private String value; ... @Id public Long getKey() { return key; } public void setKey(Long k) { key = k; } @Column public String getValue() { return value; } public void setValue(String txt) { value = txt; setLastModified(System.currentTimeMillis()); } }
The issue is that the timestamp column is not being added to the database table. Is there some annotation that needs to be added to AbstractEntity in order for the lastModified fields to be inherited as a column?
I tried adding @Entity to the AbstractEntity but that caused an exception at deployment.
org.hibernate.AnnotationException: No identifier specified for entity: AbstractEntity
-
Dobbo over 11 yearsMany thank yous Kostha - the
@MappedSuperclass
annotation was just the solution I was looking for. -
kostja over 11 yearsYou're welcome :) There's one more thing I noticed in your code, maybe you will find it useful - see the edit.
-
Dobbo over 11 yearsThanks again Kostja - your edit is exactly where I was going. As it happens I do have to modify
lastModified
myself as (some of) the entity objects are shared with the client and data is transported via XML and JAXB. -
kostja over 11 years@Dobbo I see, then you would rather want to know the actual modification time and not the persist time. Makes sense
-
Dobbo over 11 yearsYes, modification time is the way I am planning, then a task client side can poll requesting updates since the last poll. I dislike polling, but can't see an alternative given firewalling rules these days. I also plan to mark
lastUpdate
with the@Version
annotation and implement Optimistic Concurrency Control. It looks like the good fit for my client/server relationship. But if you know of a better/alternative solution I welcome suggestions.