Java – Use Hibernate/JPA persistence where object identification is important

Use Hibernate/JPA persistence where object identification is important… here is a solution to the problem.

Use Hibernate/JPA persistence where object identification is important

I use Hibernate/JPA as the persistence backend, which essentially boils down to mods for games written in Java.

In this case, it is very important for me to query the database on the main thread as little as possible. Doing this asynchronously, while possible, is impractical because I have to call GameObject methods from other threads, which is often not possible. This means that I have to do a lot of things in memory with cached objects as much as possible to maximize performance (because using memory is faster than waiting for a query to return results from the database).

Let’s say I have an entity defined as follows:

@Entity
class Town {

@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

@OneToMany(mappedBy = "town", fetch = FetchType.EAGER) // use eager fetching to save on having to query the database later for this
    private Set<Resident> residents;

// ... other fields and associated getters/setters
}

@Entity
class Resident {

@Id
    @GeneratedValue(strategy=GenerationType.IDENTITY)
    @Column(name = "id", updatable = false, nullable = false)
    private Long id;

@ManyToOne(fetch = FetchType.EAGER) // use eager fetching to save on having to query the database later for this
    @JoinColumn(name = "town_id")
    private Town town;

// ... otehr fields and associated getters/setters
}

My question is as follows:

If I were to use Hibernate to retrieve all Resident entities and store them in memory (

for example, using HashMap), then if I were to continue using Hibernate to retrieve all Town entities and cache them the same way, calling Town#getResidents() would return a reference to some identical object in memory that exists in the resident cache

Essentially, will Hibernate repopulate the newly created collection with objects that were still valid that were previously returned in the query?

Nor am I opposed to any criticism of my general approach or suggestions on how to improve it. Thank you in advance! 🙂

Solution

Caching is a very complex topic. You don’t have to deal with caching yourself. This is why hibernate< a href="https://www.baeldung.com/hibernate-second-level-cache" rel="noreferrer noopener nofollow"> second-level-cache is for.

One of the advantages of database abstraction layers such as ORM
(object-relational mapping) frameworks is their ability to
transparently cache data retrieved from the underlying store. This
helps eliminate database-access costs for frequently accessed data.

You still need to configure your entities to be cacheable and how aggressively hibernate is cached, but hibernate will handle the rest

@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
class Resident {
...

Related Problems and Solutions