【问题标题】:EclipseLink Result Cache not caching resultsEclipseLink 结果缓存不缓存结果
【发布时间】:2019-08-19 22:12:12
【问题描述】:

我想通过查询字符串+查询参数来缓存数据库查询的结果。

我正在使用 EclipseLink 的结果缓存来尝试实现这一点,但每次查询都会访问数据库。

注意:我做了一个具有相同注释和逻辑的示例,但删除了所有业务领域术语。

我已经打开了 mysql 通用查询日志,并确认查询每次都访问数据库。当我将命名查询更改为仅使用 1 个参数作为主键的查询时,查询将被缓存。

我尝试在实体上同时使用@Cache 和@Cacheable 注释,以及不使用缓存注释。

文档指出,使用结果缓存您不需要主键或索引字段。

@Entity
@Table(name = "Ball")
@XmlRootElement
@Cache
@NamedQueries({
    @NamedQuery(name="Ball.findBallWithColor",
                query="SELECT b FROM Ball b WHERE b.color = :color",
                hints = { 
                        @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE, value = "true"),
                        @QueryHint(name=QueryHints.QUERY_RESULTS_CACHE_SIZE, value = "10")
                        }
    )})
public class Blue implements Serializable {


    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    @Basic(optional = false)
    private BigInteger ballID
    private Color color;

}
public enum Color {

   BLUE,
   YELLOW,
   ORANGE,
   RED;

}

创建命名查询并执行它的代码: 在向我们的端点发出 1 个请求的过程中,此查询被多次调用,并且每次查询都会访问数据库。

public List<Ball> findBallsWithColor(Color color) {

        TypedQuery<InstitutionLtvCreditScoreGroup> query = em.createNamedQuery("Ball.findBallWithColor", Ball.class);
        query.setParameter("color", Color.BLUE);
        List<Ball> blueBalls = query.getResultList();

        return blueBalls;

    }

持久性单位:

    <persistence-unit name="Example" transaction-type="JTA">
        <provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
        <jta-data-source>${some_source}</jta-data-source>
        <exclude-unlisted-classes>false</exclude-unlisted-classes>
        <shared-cache-mode>ENABLE_SELECTIVE</shared-cache-mode>
        <properties>
            <property name="eclipselink.weaving.changetracking"
                value="false" />
            <property name="eclipselink.target-database" value="MySQL" />


            <property name="eclipselink.cache.coordination.protocol"
                value="fish.payara.persistence.eclipselink.cache.coordination.HazelcastPublishingTransportManager" />
            <property name="eclipselink.cache.coordination.channel"
                value="myChannel" />


            <property name="eclipselink.logging.logger"
                value="org.eclipse.persistence.logging.DefaultSessionLog" />
            <property name="eclipselink.logging.level" value="WARNING" />


            <property name="eclipselink.jdbc.batch-writing" value="JDBC" />

            <property name="eclipselink.jdbc.batch-writing.size"
                value="1000" />
        </properties>
    </persistence-unit>

【问题讨论】:

  • 这些查询尝试是否都在同一个 EntityManager 上下文中?您如何检查它们是否进入数据库,如果您删除共享缓存模式并使用默认值缓存注释会发生什么?
  • @Chris,感谢您的回复。我还没有尝试对我的实际应用程序进行任何进一步的调试以使结果缓存起作用。但是,我尝试制作最小的可重现示例,我发现缓存工作正常。 (使用默认设置)。这是一个链接。 github.com/TheAppFoundry/resultscaching 当我在实际应用程序上运行时,我会再次更新。我会试试你的建议

标签: jpa jakarta-ee eclipselink


【解决方案1】:

经过大量测试和阅读规范后,我实际上发现了一些非常微妙的地方,说明为什么缓存不起作用。 JPA 2.2 定义了 @Cacheable 注释,该注释可以与persistence.xml 文件中的&lt;shared-cache-mode/&gt; 属性结合使用。 我们将其定义如下:&lt;shared-cache-mode&gt;ENABLE_SELECTIVE&lt;shared-cache-mode/&gt;。这意味着在显式注释它们已缓存的实体上启用缓存。

问题是,在persistence.xml中定义的属性,我们必须在实体上使用@cacheable注解。 EclipseLink 2.7 有注释扩展,(规范中没有注释)。其中之一是 @Cache,非常相似

所以&lt;shared-cache-mode&gt;ENABLE_SELECTIVE&lt;shared-cache-mode/&gt;

@Cache
@Entity
class MyEntity {}

不会被缓存。

@Cacheable(true)
@Entity
class MyEntity{}

将被缓存。

eclipseLink 规范说使用 @Cache 代替 JPA 的 @Cacheable,但我认为这意味着我们不能使用该持久性属性。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-11-29
    • 2010-09-17
    相关资源
    最近更新 更多