Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

JPA 2 -- Using @ElementCollection in CriteriaQuery

    @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.

like image 767
nihilist84 Avatar asked Sep 14 '10 12:09

nihilist84


2 Answers

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.

like image 104
Pascal Thivent Avatar answered Oct 18 '22 18:10

Pascal Thivent


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!)

like image 2
gdt Avatar answered Oct 18 '22 20:10

gdt