【问题标题】:OpenJPA L2 Cache not caching related objectsOpenJPA L2 Cache 不缓存相关对象
【发布时间】:2014-11-13 12:25:12
【问题描述】:

我有一个简单的数据模型,它由一个与子对象列表具有一对多关系的父对象组成。

@Entity
public class Client implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @OneToMany(cascade = CascadeType.ALL)
    private List<Session> sessions;

...
}

@Entity
public class Session implements Serializable {
    @Id
    @GeneratedValue(strategy = GenerationType.IDENTITY)
    private Long id;
    @Column(length = 200)
    private String location;
...
}

我已在 persistence.xml 中使用 OpenJpa 启用 L2 缓存:

<?xml version="1.0" encoding="UTF-8"?>
<persistence version="2.0" xmlns="http://java.sun.com/xml/ns/persistence" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/persistence http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd">
  <persistence-unit name="puOpenJPA_Gym" transaction-type="JTA">
    <provider>org.apache.openjpa.persistence.PersistenceProviderImpl</provider>
    <jta-data-source>java:jboss/datasources/GymTracker</jta-data-source>
    <class>za.co.blacklemon.entities.Client</class>
    <class>za.co.blacklemon.entities.Session</class>
    <shared-cache-mode>ALL</shared-cache-mode>
    <properties>
      <property name="openjpa.jdbc.SynchronizeMappings" value="buildSchema(ForeignKeys=true)"/>
      <property name="jboss.as.jpa.providerModule" value="org.apache.openjpa"/>
      <property name="openjpa.DynamicEnhancementAgent" value="false"/>
      <property name="openjpa.Log" value="File=stdout, DefaultLevel=WARN, Runtime=INFO, Tool=INFO, SQL=TRACE"/>
      <property name="openjpa.QueryCache" value="true(CacheSize=10000, SoftReferenceSize=1000)"/>
      <property name="openjpa.DataCache" value="true(CacheSize=20000, SoftReferenceSize=1000)"/>
    </properties>
  </persistence-unit>
</persistence>

然后我通过调用 find 然后访问会话列表来获取单个客户。这里的第二行触发 OpenJPA 从 DB 中填充子对象:

Client client = dao.find(Client.class, id);
System.out.println(client.getSessions().size());

第一次运行时,日志中会出现两个查询,一个针对父对象,一个针对任何子对象:

executing prepstmnt 782097742 SELECT t0.contactNumber, t0.description, t0.firstName, t0.photo, t0.surname FROM Client t0 WHERE t0.id = ? [params=?]
executing prepstmnt 626498798 SELECT t1.id, t1.location FROM Client_Session t0 INNER JOIN Session t1 ON t0.SESSIONS_ID = t1.id WHERE t0.CLIENT_ID = ? [params=?]

第二次运行时初始查询消失了,因为对象是从缓存中检索出来的,但第二次(可能更多)查询仍在执行。

为什么 OpenJPA 不将子对象以一对多的关系存储在缓存中?

我在 Java 7 上使用 OpenJPA 2.3.0。

【问题讨论】:

  • 我发现如果您将属性标记为@OneToMany(cascade = CascadeType.ALL, fetch = FetchType.EAGER),那么它会包含在缓存中:)

标签: java caching openjpa


【解决方案1】:

为什么 OpenJPA 不将子对象以一对多的关系存储在缓存中?

OpenJPA 存储子对象,但不会将 FK 存储回父对象。我通过OPENJPA-2285 在 OpenJPA 主干(2.4.x)中修复了这个问题。

【讨论】:

  • 谢谢。我引用了最新版本,它解决了问题。
猜你喜欢
  • 2023-04-09
  • 2014-10-30
  • 2019-08-08
  • 2017-01-11
  • 2011-09-06
  • 2011-02-17
  • 2016-03-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多