Java – Jpa query pulling from cache instead of database


I am hitting an issue with my Hibernate backed Jpa queries returning data that is not up to date. I assume it is an issue with pulling data from the cache instead of the database itself.

For example, I will change and persist an object on one page and then go back to the previous page, which lists rows of the database, and it will show the objects as they existed prior to the change. I can see my query fire from my DAO in my logs and I can go into the database and see that the changes have been persisted, but JPA is not pulling up to date data from the database when I move on to the next page.

I believe there might be some kind of session caching at work, as I will not see an updated database view when I load the page up in another web browser.

How do I fix this issue?

EDIT: I've done some follow up testing, including logging on my controller to make sure my MVC framework (Spring MVC) isn't caching anything. It isn't, even on the controller level it sees out of date database information.

Here is the mapping snippet from my ORM entity file;

private static final long serialVersionUID = 1L;
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Basic(optional = true)
@Column(name = "ID", nullable = false)
private Integer id;
@Basic(optional = false)
@Column(name = "Name", nullable = false, length = 100)
private String name;
@Basic(optional = false)
@Column(name = "DayOffset", nullable = false)
private int dayOffset;
@Basic(optional = false)
@Column(name = "StartTime", nullable = false, length = 5)
private String startTime;
@Basic(optional = false)
@Column(name = "Enabled", nullable = false)
private boolean enabled;
@Basic(optional = false)
@Column(name = "LastTouched", insertable = false, updatable = false, nullable =
private Date lastTouched;
@Column(name = "TouchedBy", length = 50)
private String touchedBy;
@JoinTable(name = "ReconciliationSearchRule",
joinColumns = {@JoinColumn(name = "ReconciliationId",
    referencedColumnName = "ID", nullable = false)},
inverseJoinColumns = {@JoinColumn(name = "SearchRuleId",
    referencedColumnName = "ID", nullable = false)})
@ManyToMany(fetch = FetchType.LAZY)
private Collection<SearchRule> searchRuleCollection;
@JoinColumn(name = "ServerId", referencedColumnName = "ID", nullable = false)
@ManyToOne(optional = false, fetch = FetchType.LAZY)
private Server server;
@OneToMany(mappedBy = "reconciliation")
private Collection<Report> reportCollection;

Best Solution

I figured out what was going on. My DAO is being injected as a prototype (aka non-singleton) so the backing EntityManager was being created for each use of the DAO. Database changes external to the EntityManager are not registered by queries to that particular EntityManager.

Of course setting the DAO to a singleton causes other issues with the multi-threaded part of my application, but that is a whole other issue.

Related Question