Warning: file_get_contents(/data/phpspider/zhask/data//catemap/0/jpa/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Jsf JPA EclipseLink实体未刷新_Jsf_Jpa_Eclipselink - Fatal编程技术网

Jsf JPA EclipseLink实体未刷新

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

当数据库中的值从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;
    ...

}
我在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);
}