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
Java 使用JPA获取旧数据_Java_Jpa_Eclipselink - Fatal编程技术网

Java 使用JPA获取旧数据

Java 使用JPA获取旧数据,java,jpa,eclipselink,Java,Jpa,Eclipselink,我使用JPA获取旧数据,即使我禁用了缓存。我猜是因为资源配置为resource_LOCAL,但我不确定 org.eclipse.persistence.jpa.PersistenceProvider com.myentities.User 获取有关用户的旧信息的我的代码: public List<User> findAll(App app) { getEntityManager().getTransaction().begin();

我使用JPA获取旧数据,即使我禁用了缓存。我猜是因为资源配置为resource_LOCAL,但我不确定


org.eclipse.persistence.jpa.PersistenceProvider
com.myentities.User
获取有关用户的旧信息的我的代码:

public List<User> findAll(App app) {       
        getEntityManager().getTransaction().begin();        
        Query q = getEntityManager().createQuery("SELECT t1 FROM User t1 WHERE t1.app.idApp=:idApp");
        q.setParameter("idApp", app.getIdApp());
        getEntityManager().flush();
        getEntityManager().getTransaction().commit();
        List resultList = q.getResultList();        
        return resultList;
    }
有人知道发生了什么吗

更新1 begin、flush和commit方法只是绝望的行为!我知道不需要

我忘了说一些重要的话:我做的测试是直接在数据库控制台上添加一条用户记录,然后尝试通过我的webapp查看它,它没有显示新用户。这就是我提到的“旧数据”,它只显示“旧用户”

我已经尝试将其设置为persistence.xml,结果没有任何差异:


还有别的东西吗…

<property name="eclipselink.cache.shared.default" value="false"/>
<property name="eclipselink.cache.size.default" value="0"/>
<property name="eclipselink.cache.type.default" value="None"/>

与缓存答案(我将不得不尝试)相反,您可能会遇到引用实体未更新的情况

@Entity
Class Parent
{
  @OneToOne(Cascade.ALL)//Or only Merge, whatever you're needs
  Child child;
}

@Entity
Class Child
{
  Parent parent;
  ... Values
}
保存子级后,需要更新对父级的引用,以便内存模型(缓存)与数据库匹配。这是相当令人沮丧的,但我处理这个问题的方法是只从父级级联

public void saveChild(Child child)
{
  child.getParent().setChild(this); //or DTO Code, whatever
  EntityManager.merge(parent); //cascades to the child.
  //If you're manually cascading (why?) 
  //EntityManager.merge(child);
}
如果你设置它,它会级联——我看到的是反向级联(子合并导致级联到父级)不可靠——这是由于我对该主题缺乏了解


简言之,如果显式地处理数据层中的合并,问题就会消失。我不愿意禁用缓存,因为它可能会对大型应用程序产生重大影响,因此,我选择了这条路线。祝您好运,请告诉我们您的方法。

已经发布了一些建议,例如确保共享缓存已关闭,以及管理反向引用以使缓存一致。这些是针对可能发生的特定情况,但您没有提供足够的信息来说明真正发生了什么

另一个是特定的,但根据getEntityManager()的使用情况,可能是重用EntityManager实例而不清除它。EntityManager保存对所有托管实体的引用,因为EM需要在后续查询中返回同一实例,并查找用于维护标识的调用

如果尚未执行此操作,则需要清除EntityManager或在某些点获取新的EntityManager,以释放内存和受管实体

首先,不要使用

@Cache(type=CacheType.NONE)
or,
<property name="eclipselink.cache.size.default" value="0"/>
or,
<property name="eclipselink.cache.type.default" value="None"/>
@Cache(type=CacheType.NONE)
或
或
刚刚好

@Cache(shared=false)
or,
<property name="eclipselink.cache.shared.default" value="false"/>
@缓存(shared=false)
或
第二,您的EntityManager来自哪里?您是否为每个请求/事务创建一个新的请求/事务?如果不这样做,则EntityManager中读取的所有内容都将在其(一级)缓存中。您需要调用clear()或创建一个新的。

1)优化代码

public List<User> findAll(App app) {   
    Query q = getEntityManager().createQuery("SELECT t1 FROM User t1 WHERE    t1.app.idApp=:idApp");    q.setParameter("idApp", app.getIdApp());                 
    List resultList = q.getResultList();            
    return resultList;    
} 
公共列表findAll(App){
Query q=getEntityManager().createQuery(“从用户t1中选择t1,其中t1.app.idApp=:idApp”);q.setParameter(“idApp”,app.getIdApp());
List resultList=q.getResultList();
返回结果列表;
} 
2) 从实体类中删除@Cache(type=CacheType.NONE)


3) 无需更改persistence.xml

EntityManager的使用是关键。几个月后,我找到了完美的解决方案:

  • 对实体的所有读取使用通用默认实体管理器。这意味着为每个实体创建一个单独的实体管理器
  • 为每个实体的每个写入/更新/删除操作创建一个新的实体管理器。对该新实体的事务使用begin/commit。操作完成后关闭实体管理器
  • 节点点:提交并关闭writer实体管理器后,清除默认实体管理器(reader one)。这意味着只有在写后才清楚;每次阅读前都不要

1)仅查询时,不需要启动/刷新/提交任何事务。2) “sistema”对象来自哪里?为什么方法中没有使用“app”参数?这是整个方法吗?刷新和提交在这里没有任何意义。数据以何种方式过时?怎么了?在EntityManager的范围内,您还做了什么?在打开和关闭EM之间进行的所有调用/更改是什么?有人猜测您让实体的内存状态与数据库不同步。您是对的!问题出在我的经理身上。这不是关于EclipseLink缓存或类似的东西。谢谢任何人都可以请,描述一点关于清除EM和重用它。我是JPA的新手。我的问题是,如果我手动修改表中的两行(为了测试),应用程序将获取第一个修改行的新数据,但获取第二个修改行的旧数据。我在em.ceateNamedQuery(..)之前执行em.clear()。好吗?@Dexter我的建议是,如果可能的话,避免使用DML执行CUD,因为您可能会遇到问题。如果必须,在DML执行后调用
clear()
refresh()
,您可以在链接中找到更多信息。
@Cache(shared=false)
or,
<property name="eclipselink.cache.shared.default" value="false"/>
public List<User> findAll(App app) {   
    Query q = getEntityManager().createQuery("SELECT t1 FROM User t1 WHERE    t1.app.idApp=:idApp");    q.setParameter("idApp", app.getIdApp());                 
    List resultList = q.getResultList();            
    return resultList;    
}