@Entity
public class Person {
@ElementCollection
private List<Location> locations;
[...]
}
@Embeddable
public class Location {
private Integer dummy;
private Date creationDate;
[...]
}
Given the following structure, I'd like to perform the HQL or CriteriaQuery equivalent of the following SQL:
SELECT
l.*
FROM
Location l
INNER JOIN
Person p ON (p.id = l.person_id)
WHERE
p.id = ? AND l.creationDate > ?
I want to get back a list of Locations that are associated with the given person and whose creationDate is after the given one.
Thanks in advance!
Mark
Edit***: I have edited the SQL, as it was kinda misleading. I don't want to query for the locations independently.
This is not possible, you cannot query an Embeddable
. From the JPA Wikibook:
Embedded Collections
An ElementCollection
mapping can be
used to define a collection of
Embeddable
objects. This is not a
typical usage of Embeddable
objects
as the objects are not embedded in the
source object's table, but stored in a
separate collection table. This is
similar to a OneToMany
, except the
target object is an Embeddable
instead of an Entity
. This allows
collections of simple objects to be
easily defined, without requiring the
simple objects to define an Id
or
ManyToOne
inverse mapping.
ElementCollection
can also override
the mappings, or table for their
collection, so you can have multiple
entities reference the same Embeddable
class, but have each store their
dependent objects in a separate table.
The limitations of using an
ElementCollection
instead of a
OneToMany
is that the target
objects cannot be queried,
persisted, merged independently of
their parent object. They are strictly
privately-owned (dependent) objects,
the same as an Embedded
mapping.
There is no cascade option on an
ElementCollection
, the target
objects are always persisted, merged,
removed with their parent.
ElementCollection
still can use a
fetch type and defaults to LAZY the
same as other collection mappings.
To achieve what you want, use a OneToMany
and an Entity
instead of an ElementCollection
and an Embeddable
. Or change your approach and query the Person
.
The key phrase in Pascal's reply is
the target objects cannot be queried, persisted, merged independently of their parent object
As you are dependent on the parent object, you should be able to do this using something like ...
SELECT p FROM PERSON, IN (p.locations) WHERE p.id = ?1 AND locations = ?2
(Based on the reply at Execute "MEMBER OF" query against 'ElementCollection' Map fields in JP-QL (JPA 2.0) - which is actually a Map @ElementCollection which was what I was looking for an answer to!)