2

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;
@Id
@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 =
false)
@Temporal(TemporalType.TIMESTAMP)
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;
2
  • What do you mean by "I can see my query fire from my DAO"? Do you mean that you see SQL being sent to the database? How do you know you're correctly persisting the change in the first place? Commented Dec 4, 2009 at 19:02
  • how do you save your entity ? EntityManager.persist() or .merge() ? Commented Dec 4, 2009 at 19:29

3 Answers 3

4

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.

Sign up to request clarification or add additional context in comments.

Comments

0

There are a couple ways of going about this:

  1. Set an eviction strategy using the @DataCache(timeout = 1000) on the entity in question and set it to something reasonable for the object type you are using.
  2. Call evict(...) on your entity or class. The implementation details of this are specific based upon what provider (e.g. Hibernate) you are using.

6 Comments

For 1, could you explain in more detail with @DataCache would go? For 2, which class has the evict method? Thank you.
Hibernate Session has evict(), which isn't suitable for you ;)
@DataCache is an annotation that you put on the class that is not refreshed (because it is cached). This annotation will instruct JPA to evict (or clear) the cache for objects of this type on the frequency specified via the timeout parameter.
@rynmrtn, So you put on your entity class in the ORM layer. What is the default for @DataCache? And where can I find the java docs?
@rynmrtn, is @DataCache a Hibernate annotation? My IDE has no idea where to import it from and I have had no luck finding the docs for it. If it is Hibernate, I can't use it directly because I am trying to work through JPA.
|
0

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.

Second level cache management should be transparent, you don't have to evict() an entity manually after any update, the 2nd level cache gets invalidated for the target table "automatically" by Hibernate.

So, my question is: what do you mean by "going back to the previous page"? Do you mean using the navigator "Back" button? Did you reload the page? Can you clarify this?

Also, can you post your mapping file or annotated entity?

1 Comment

Pascal, by going back I click a hyperlink that takes me to another page. I will post up some more information when I am at work Monday.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.