从缓存而不是数据库拉jpa查询?

时间:2009-12-04 18:56:39

标签: java hibernate orm jpa persistence

我遇到的问题是我的Hibernate支持的Jpa查询返回的数据不是最新的。我认为从缓存而不是数据库本身提取数据是一个问题。

例如,我将在一个页面上更改并保留一个对象,然后返回上一页,该页面列出了数据库的行,并且它将显示更改前存在的对象。我可以在我的日志中看到我的DAO中的查询,我可以进入数据库并看到更改已经保留,但是当我转到下一页时,JPA没有从数据库中提取最新数据。 / p>

我相信在工作中可能会有某种会话缓存,因为当我在另一个Web浏览器中加载页面时,我不会看到更新的数据库视图。

如何解决此问题?

编辑:我做了一些后续测试,包括登录我的控制器以确保我的MVC框架(Spring MVC)没有缓存任何东西。它不是,即使在控制器级别上它也会看到过时的数据库信息。


以下是我的ORM实体文件中的映射片段;

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;

3 个答案:

答案 0 :(得分:3)

我弄清楚发生了什么事。我的DAO被注入原型(也称为非单例),因此为每次使用DAO创建了支持EntityManager。 EntityManager外部的数据库更改未通过查询注册到该特定EntityManager。

当然,将DAO设置为单例会导致我的应用程序的多线程部分出现其他问题,但这是另一个问题。

答案 1 :(得分:0)

有几种方法可以解决这个问题:

  1. 使用相关实体上的@DataCache(timeout = 1000)设置驱逐策略,并将其设置为您正在使用的对象类型的合理范围。
  2. 在您的实体或班级上致电evict(...)。具体的实现细节是基于您正在使用的提供程序(例如Hibernate)。

答案 2 :(得分:0)

  

例如,我将在一个页面上更改并保留一个对象,然后返回上一页,该页面列出了数据库的行,并且它将显示更改前存在的对象。

二级缓存管理应该是透明的,在任何更新之后您不必手动evict()一个实体,二级缓存会被Hibernate“自动”地对目标表无效。

所以,我的问题是:你是什么意思“回到上一页”?你的意思是使用导航器“后退”按钮?你重新加载页面了吗?你能澄清一下吗?

另外,您可以发布您的映射文件或带注释的实体吗?