I am using Hibernate/JPA as the persistence backend to what essentially boils down to a mod to a game written in Java.
In this context, it is very important to me that I query the database as rarely as possible on the main thread. Doing so asynchronously, while possible, would be impractical as I would have to call methods of game objects from other threads, which more often than not will not work. This means I have to do as many things as possible in memory using cached objects as I can, to maximize performance ( as working with memory would be faster than having to wait for a query to return results from the database ).
Say I have entities 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 the following:
If I were to retrieve all Resident entities using Hibernate, and store them in memory ( say, using a HashMap ), and if I were to then proceed to retrieve all Town entities using Hibernate and cache them the same way, will calling Town#getResidents()
return references to some of the same objects in memory as are present in the Resident cache?
Essentially, does Hibernate re-use still-valid objects which have previously been returned in queries to populate newly created collections?
I would also not be against any criticism of my general approach or advice on how I could improve it. Thank you in advance! :)
Caching is a really complex topic. You should not have to take care of caching by yourself. That's what hibernates 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 have to configure your Entities to be cacheable and how aggressively hibernate should cache, but the rest will be handled by hibernate
@Entity
@Cache(usage = CacheConcurrencyStrategy.READ_WRITE)
class Resident {
...