Tip:
Highlight text to annotate it
X
Hi, I’m Thorben Janssen from thoughts-on-java.org
with a new Hibernate Tip.
One of the readers of my blog asked me this question:
Some of our entities have a lot of attributes
and we don’t need all of them in all use cases.
Can I create a second entity that only maps a subset of the most commonly used attributes?
Is there anything I should consider?
Yes, you can map two or more entities to the same database table.
But you should only do that if you will use
all of these entities to perform write operations
or to define associations between entities.
If that’s not the case, you should better use a DTO projection.
As I’ve showed in one of my blog posts,
DTOs perform a lot better for read operations.
You can find a link to it in the video description.
OK, let’s talk about the entity mappings.
And please make sure to watch until the end of this video.
There are a few side-effects which you should be aware of
before you start mapping multiple entities
to the same database table.
But more about that later.
If you want to map the same database table to two entities,
you should create a simple inheritance hierarchy.
The superclass,
in this example a class called AbstractAuthor,
should be abstract
and contain all attributes
that are shared by both entities.
You should map it as a mapped superclass
so that it is not an entity itself.
Let’s take a look at the code.
Here you can see the AbstractAuthor entity.
It’s abstract, annotated with MappedSuperclass
and defines the mapping of all shared attributes.
The class AuthorShort maps
only the most commonly used attributes.
It extends the superclass
and doesn’t add any attributes itself.
By default,
Hibernate would map this entity
to the database table AuthorShort.
You can override the default table mapping
with the Table annotation
and specify the table name in the name attribute.
And the Author entity
maps all columns of the author table.
So, it needs to provide the mapping information of the
not commonly used attributes
that are not already defined by the AbstractAuthor class
That’s all you need to do to map
2 entities to the same database table.
But there are a few things
you need to keep in mind
before you implement your use cases.
Even so, you told Hibernate to map both entities to the same database table;
Hibernate doesn’t know which Author and AuthorShort entities
represent the same database record.
That has a few implications:
First of all
Hibernate doesn’t refresh any of these entities
if you update the other one.
So, you need to either take care of that yourself
or make one of the entities immutable.
The second issue is, Hibernate stores all managed entities in
the 1st level cache
and delays all write operations
until it flushes the persistence context.
This happens transparently so that you normally don’t recognize it.
But that changes when you map 2 entities to the same database table.
A call of the EntityManager.find method
to load an AuthorShort entity
doesn’t trigger a flush of the Author entities.
So, Hibernate doesn’t write the pending changes to the database
and the find method
might return an outdated entity.
and the third issue is that Hibernate handles the Author
and AuthorShort entities
independently of each other.
Hibernate will throw an OptimisticLockException
if you update an AuthorShort
and an Author entity
that map the same database record
within the same transaction.
OK, that’s it for today.
If you want to learn more about Hibernate,
you should join the free Thoughts on Java Library.
It gives you free access to a lot of member-only content
like an ebook about the Java 8 support in Hibernate,
a printable PDF version of this Hibernate Tip,
lots of cheat sheets and a video course.
I’ll add the link to it to the video description below.
See you next week for a new Hibernate Tip
and if you like today’s video,
please give it thumbs up and subscribe below.
Bye