Jsf JPA EclipseLink实体未刷新
当数据库中的值从JPA会话外部更改时,实体没有被刷新,这是一个问题。例如,我有一个用户实体:Jsf JPA EclipseLink实体未刷新,jsf,jpa,eclipselink,Jsf,Jpa,Eclipselink,当数据库中的值从JPA会话外部更改时,实体没有被刷新,这是一个问题。例如,我有一个用户实体: @Entity @Cacheable(false) public class UserBean implements Serializable { @Id @GeneratedValue(strategy = GenerationType.AUTO) private long id; @OneToMany(mappedBy = "receiver") @Joi
@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;
...
}
我在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>
通知已更新
我需要从数据库中刷新的变量比通知多,对每个通知执行相同操作需要大量代码。我认为em.refresh(user)
应该为我重新加载数据库中已更改的所有变量。我认为这是一个缓存问题,所以我在UserBean
和NotificationBean
中添加了@Cacheable(false)
,但没有效果
我做错了什么?如果问题在于通知,那么这是因为刷新用户未设置为级联刷新。在notificationsReceived映射上设置CascadeType.REFRESH。在UserBean中,我将@OneToMany(mappedBy=“receiver”)更改为@OneToMany(mappedBy=“receiver”,cascade=“CascadeType.REFRESH”),但没有效果。还有其他想法吗?现在您需要调用em.refresh(user),或者将“eclipselink.refresh”查询提示添加到引入user:query.setHint的查询中(“eclipselink.refresh”,true);很抱歉,我没有提到我将refreshUser更改回:public void refreshUser(EntityManagerFactory emf){EntityManager em=emf.createEntityManager();em.refresh(em.merge(user));},现在我看到了错误所在。如果我只放em.refresh(user),我会得到一个错误,用户不是由EntityManager管理的,所以我添加了merge(user)来修复这个错误,但是它没有正常工作,我认为merge重写了对用户外部所做的所有更改。现在,我将用户和EM重新关联为:user=EM.find(user.getClass(),user.getId());然后使用以下命令刷新:em.refresh(user);谢谢你的帮助!
<f:metadata>
<f:event type="preRenderView" listener="#{sessionManager.refreshUser()}" />
</f:metadata>
public void refreshUser() {
EntityManager em = emf.createEntityManager();
List<NotificationBean> notifications = em.createNativeQuery("SELECT * FROM NOTIFICATIONBEAN WHERE RECEIVER_ID = " +
user.getId() + ";").getResultList();
user.setMatchChallengesReceived(notifications);
}