当从JPA会话外部更改数据库中的值时,我遇到了无法刷新实体的问题。例如,我有一个用户实体:
@Entity
@Cacheable(false)
public class UserBean implements Serializable {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
private long id;
@OneToMany(mappedBy = "receiver")
@JoinTable(name = "NOTIFICATIONS_RECEIVED")
private List<NotificationBean> notificationsReceived;
...
}
通知实体:
@Entity
@Cacheable(false)
public class NotificationBean implements Serializable{
@Id
@GeneratedValue
private Long id;
@ManyToOne
private UserBean receiver;
...
}
我在JSF应用程序中使用它并且有一个SessionScoped bean,它在登录后加载用户并存储它:
@Named("sessionManager")
@SessionScoped
public class SessionManagerBean implements Serializable {
@PersistenceUnit(unitName = "PU")
private EntityManagerFactory emf;
private UserBean user;
public UserBean getUser() throws Exception {
if (user == null) {
FacesContext context = FacesContext.getCurrentInstance();
HttpServletRequest request = (HttpServletRequest) context.getExternalContext().getRequest();
String username = request.getRemoteUser();
if (username != null) {
EntityManager em = null;
try {
utx.begin();
em = emf.createEntityManager();
Query query = em.createQuery("SELECT u from UserBean u WHERE u.username = ?1");
query.setParameter(1, username);
user = (UserBean) query.getSingleResult();
}
catch (Exception e) {
try {
utx.rollback();
} catch (Exception e) {
} finally {
utx.commit();
em.close();
}
}
return user;
}
}
}
public void refreshUser() {
EnitytManager em = emf.createEntityManager();
// similar code as above to retrieve the user from the database
em.refresh(user);
}
}
显示通知的页面在加载时调用refreshUser()
:
<f:metadata>
<f:event type="preRenderView" listener="#{sessionManager.refreshUser()}" />
</f:metadata>
用户数据虽然没有刷新,但刷新页面时页面上显示的通知不会更新。
但是,如果我将refreshUser()
更改为:
public void refreshUser() {
EntityManager em = emf.createEntityManager();
List<NotificationBean> notifications = em.createNativeQuery("SELECT * FROM NOTIFICATIONBEAN WHERE RECEIVER_ID = " +
user.getId() + ";").getResultList();
user.setMatchChallengesReceived(notifications);
}
通知已更新。
我有更多变量而不是我需要从数据库刷新的通知,并且每个都需要做很多相同的代码。我认为em.refresh(user)
应该为我重新加载从数据库中更改的所有变量。我认为这是一个缓存问题,因此我将@Cacheable(false)
添加到UserBean
和NotificationBean
,但它没有效果。
我做错了什么?
答案 0 :(得分:3)
如果问题出在通知上,那么因为刷新用户未设置为级联刷新。在notificationsReceived映射上设置CascadeType.REFRESH。