A possible solution other than queries might be mapping children
with lazy="extra"
(in XML notation). This way, you can fetch the Parent with whatever query you need, then call parent.getChildren().size()
without loading the whole collection (only a SELECT COUNT
type query is executed).
With annotations, it would be
@OneToMany
@org.hibernate.annotations.LazyCollection(
org.hibernate.annotations.LazyCollectionOption.EXTRA
)
private Set<Child> children = new HashSet<Child>();
Update: Quote from Java Persistence with Hibernate, ch. 13.1.3:
A proxy is initialized if you call any method that is not the identifier getter
method, a collection is initialized if you start iterating through its elements or if
you call any of the collection-management operations, such as size()
and contains()
.
Hibernate provides an additional setting that is mostly useful for large collections; they can be mapped as extra lazy. [...]
[Mapped as above,] the collection is no longer initialized if you call size()
, contains()
, or isEmpty()
— the database is queried to retrieve the necessary information. If it’s a Map
or a List
, the operations containsKey()
and get()
also query the database directly.
So with an entity mapped as above, you can then do
Parent p = // execute query to load desired parent
// due to lazy loading, at this point p.children is a proxy object
int count = p.getChildren().size(); // the collection is not loaded, only its size
与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…