Spring/Hibernate:双向映射,仅针对 JPQL 查询不同步
Spring/Hibernate: Bidirectional Mapping without synchronization for JPQL queries only
在实体之间的双向映射中(例如@ManyToOne
↔ @OneToMany
),对应对象需要是synchronized on every change,尤其是在使用2nd[=时44=]级缓存。这通常是通过辅助方法完成的。如果 Many
部分包含大量条目,这些辅助方法将无法正常执行,因为每次都会获取整个集合。一个简单的例子是实体 Store
具有 n
Products
,而 n
非常大。将新的 Product
添加到 Store
将需要 Store
获取 Products
的整个列表以最终将其添加到集合中(参见下面的代码示例)。
有人可能会争辩说,在对这种关系建模时,最好用从 Product
到 Store
的单向关联来表示。不过,我们在我们的应用程序中使用了许多 JPQL 查询。在 JPQL 中,连接两侧的实体非常方便。
在 Store
实体中映射 @OneToMany
关系时,您是否看到任何问题,当 Many
实际上意味着很多而不仅仅是几个,并且只是将字段设为私有,没有 getter 和 setter,前提是整个关系都是懒惰获取的?据我了解,Hibernate 只需要字段来映射关系。如果集合是私有的,应该不会出现性能问题?
Product
实体:
@Entity
@Table(name = "product")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Product {
@ManyToOne(fetch = FetchType.LAZY)
private Store store;
// setter, getter, helper methods
}
Store
实体:
@Entity
@Table(name = "store")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Store {
@OneToMany(mappedBy = "products", fetch = FetchType.LAZY)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Product> products;
// setter, getter, helper methods
}
不,没有错,这也是我经常使用的技巧。当然,只要确保在某些情况下不会反射访问该字段(例如自动 toString
构建器和您可能正在使用的类似实用程序)。
此外,您不需要在其上添加 @Cache
注释,因为您永远不会访问该集合,因此它永远不会被缓存。
在实体之间的双向映射中(例如@ManyToOne
↔ @OneToMany
),对应对象需要是synchronized on every change,尤其是在使用2nd[=时44=]级缓存。这通常是通过辅助方法完成的。如果 Many
部分包含大量条目,这些辅助方法将无法正常执行,因为每次都会获取整个集合。一个简单的例子是实体 Store
具有 n
Products
,而 n
非常大。将新的 Product
添加到 Store
将需要 Store
获取 Products
的整个列表以最终将其添加到集合中(参见下面的代码示例)。
有人可能会争辩说,在对这种关系建模时,最好用从 Product
到 Store
的单向关联来表示。不过,我们在我们的应用程序中使用了许多 JPQL 查询。在 JPQL 中,连接两侧的实体非常方便。
在 Store
实体中映射 @OneToMany
关系时,您是否看到任何问题,当 Many
实际上意味着很多而不仅仅是几个,并且只是将字段设为私有,没有 getter 和 setter,前提是整个关系都是懒惰获取的?据我了解,Hibernate 只需要字段来映射关系。如果集合是私有的,应该不会出现性能问题?
Product
实体:
@Entity
@Table(name = "product")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Product {
@ManyToOne(fetch = FetchType.LAZY)
private Store store;
// setter, getter, helper methods
}
Store
实体:
@Entity
@Table(name = "store")
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
public class Store {
@OneToMany(mappedBy = "products", fetch = FetchType.LAZY)
@Cache(usage = CacheConcurrencyStrategy.NONSTRICT_READ_WRITE)
private Set<Product> products;
// setter, getter, helper methods
}
不,没有错,这也是我经常使用的技巧。当然,只要确保在某些情况下不会反射访问该字段(例如自动 toString
构建器和您可能正在使用的类似实用程序)。
此外,您不需要在其上添加 @Cache
注释,因为您永远不会访问该集合,因此它永远不会被缓存。