1

I am trying to learn Java Persistance API. So it is written on page174 of JPA 2.1 specification :

In the following example, contactInfo denotes an embeddable class consisting of an address and set of phones. Phone is an entity.

SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p
WHERE e.contactInfo.address.zipcode = '95054' 

The following query is equivalent to the query above:

SELECT p.vendor FROM Employee e JOIN e.contactInfo c JOIN c.phones p WHERE e.contactInfo.address.zipcode = '95054'

then on page 176: The query below joins over Employee, ContactInfo and Phone. ContactInfo is an embeddable class that consists of an address and set of phones. Phone is an entity.

SELECT p.vendor FROM Employee e JOIN e.contactInfo c JOIN c.phones p WHERE c.address.zipcode = '95054'

So when I try to execute such queries only the first works. The last two queries cause error: Exception in thread "main" java.lang.IllegalArgumentException: An exception occurred while creating a query in EntityManager: Exception Description: Problem compiling [SELECT p.vendor FROM Employee e JOIN e.contactInfo c JOIN c.phoneNumbers p WHERE c.address.zipcode = 'zip2']. [37, 50] The collection-valued path 'e.contactInfo' must resolve to an association field.

Could anyone explain why is that? I also tried to reproduce other examples of joins to embeddable classes from the specification, but always got the same error.

Thank you Best regards

user3120128
  • 21
  • 1
  • 5

1 Answers1

0

Embeddable can not be used in join operations.

If you said that contactInfo is an embeddable this can not be done.

SELECT p.vendor FROM Employee e JOIN e.contactInfo

Also

SELECT p.vendor FROM Employee e JOIN e.contactInfo.phones p WHERE e.contactInfo.address.zipcode = '95054'

is not equivalent to

SELECT p.vendor FROM Employee e JOIN e.contactInfo c JOIN c.phones p WHERE e.contactInfo.address.zipcode = '95054'

e.contactInfo.phones should be a collection value, meanwhile e.contactInfo is just an embeddable

Probably the mapping for ContactInfo is something like this.

@Embeddable
public class ContactInfo{
 @OneToMany
 private Collection<Phone> phones;
}
Koitoer
  • 18,778
  • 7
  • 63
  • 86
  • Thanks for the reply. Yes, it seems impossible to use embeddable classes in joins. But as you see, in the unmodified quotes from the specification it is stated repeatedly that ContactInfo is an embeddable class. There is its code on page 459. Why is there such discrepancy between the specificaton and its implementation? – user3120128 Apr 02 '14 at 07:16
  • From where you obtain those specs I check the official for Oracle and those pages does not say nothing similar http://download.oracle.com/otn-pub/jcp/persistence-2_1-pr-spec/JavaPersistencePDR.pdf?AuthParam=1396453203_b4a67c5141154ebe083305894e1644f6 – Koitoer Apr 02 '14 at 15:43
  • The link you provided is the Public Review Draft. The Final Release is here: https://jcp.org/aboutJava/communityprocess/final/jsr338/index.html – user3120128 Apr 02 '14 at 15:59
  • I read it and I think you found an error in the specs, try to send an email to the Java Persistence 2.1 Expert Group, and dong forget to let me know in which finish this XD. – Koitoer Apr 02 '14 at 16:08