質問

I'm using Toplink Grid(Eclipselink) as the my JPA implementation framework.

I met a a exception as below while I tried to use Criteria to query a Embeddable object:

 Exception [EclipseLink-6119] (Eclipse Persistence Services - 2.1.2.v20101206-r8635): org.eclipse.persistence.exceptions.QueryException
Exception Description: The join expression 
Query Key conInfo
   Base domain.de1003.Employee is not valid, or for a mapping type that does not support joining.
Query: ReportQuery(referenceClass=Employee )
    at org.eclipse.persistence.exceptions.QueryException.mappingForExpressionDoesNotSupportJoining(QueryException.java:659)
    at org.eclipse.persistence.internal.queries.JoinedAttributeManager.prepareJoinExpression(JoinedAttributeManager.java:851)
    at org.eclipse.persistence.internal.queries.JoinedAttributeManager.prepareJoinExpressions(JoinedAttributeManager.java:778)
    at org.eclipse.persistence.internal.queries.ReportItem.initialize(ReportItem.java:171)
    at org.eclipse.persistence.queries.ReportQuery.prepare(ReportQuery.java:1035)
    at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:509)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:822)
    at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:470)
    at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:710)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1038)
    at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:381)
    at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1124)
    at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2917)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1291)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1273)
    at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1247)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.executeReadQuery(EJBQueryImpl.java:479)
    at org.eclipse.persistence.internal.jpa.EJBQueryImpl.getResultList(EJBQueryImpl.java:714)

And the code I tried are as below:

CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery<ContactInfo> cq = cb.createQuery(ContactInfo.class);
Root<Employee> root = cq.from(Employee.class);
cq.select(root.<ContactInfo> get("conInfo"));
cq.where(cb.le(root.<Long> get("employId"), 3));

TypedQuery<ContactInfo> q = em.createQuery(cq);
List<ContactInfo> results = q.getResultList();

In Which ContactInfo is an embeddable class consisting of an address and set of phones. Phone is String filed.

Any help will be very appreciated.

I check the question related to this issue: JPA - Criteria API and EmbeddedId

But it didn't solve my question.

And I can't find any example code.

TO James:

The entity code as below:

    package domain.de1003;

import java.io.IOException;
import java.io.Serializable;
import java.util.List;

import javax.persistence.AttributeOverrides;
import javax.persistence.AttributeOverride;
import javax.persistence.CascadeType;
import javax.persistence.CollectionTable;
import javax.persistence.Column;
import javax.persistence.ElementCollection;
import javax.persistence.Embedded;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.OneToMany;
import javax.persistence.Table;
import javax.persistence.Version;

import oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer;

import org.eclipse.persistence.annotations.Customizer;

import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;

@Entity(name="Employee")
@Table(name="EMPLOYEE")
@Customizer(oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer.class)
public class Employee implements PortableObject,Serializable {

private static final long serialVersionUID = 1L;
@Id
@Column(name = "EM_ID")
private long employId;

@Column(name = "FIRSTNAME")
private String firstName;

@Column(name = "LASTNAME")
private String lastName;

@Embedded
@AttributeOverrides({
    @AttributeOverride(name="homePhone", column=@Column(name="HOMEPHONE")),
    @AttributeOverride(name="workPhone", column=@Column(name="WORKPHONE"))
})
private ContactInfo conInfo;

@Version
private long version;

public long getEmployId() {
    return employId;
}

public void setEmployId(long employId) {
    this.employId = employId;
}

public String getFirstName() {
    return firstName;
}

public void setFirstName(String firstName) {
    this.firstName = firstName;
}

public String getLastName() {
    return lastName;
}

public void setLastName(String lastName) {
    this.lastName = lastName;
}

public ContactInfo getConInfo() {
    return conInfo;
}

public void setConInfo(ContactInfo conInfo) {
    this.conInfo = conInfo;
}

public long getVersion() {
    return version;
}

public void setVersion(long version) {
    this.version = version;
}

@Override
public void readExternal(PofReader pofReader) throws IOException {
    employId = pofReader.readLong(1);
    firstName = pofReader.readString(2);
    lastName = pofReader.readString(3);
    version = pofReader.readLong(4);

}

@Override
public void writeExternal(PofWriter pofWriter) throws IOException {
    pofWriter.writeLong(1, employId);
    if(firstName != null) pofWriter.writeString(2, firstName);
    if(lastName != null) pofWriter.writeString(3,lastName);
    pofWriter.writeLong(4, version);
}

@Override
public String toString() {
    return "[" 
    + "employId = " + employId
    + " firstName = " + firstName
    + " lastName = " + lastName
    + " contact inforamtion: " + conInfo
    + "]";
}

}

and Entity ContactInfo

    package domain.de1003;

import java.io.IOException;
import java.io.Serializable;

import javax.persistence.Column;
import javax.persistence.Embeddable;

import oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer;

import org.eclipse.persistence.annotations.Customizer;

import com.tangosol.io.pof.PofReader;
import com.tangosol.io.pof.PofWriter;
import com.tangosol.io.pof.PortableObject;

@Embeddable
@Customizer(oracle.eclipselink.coherence.integrated.config.GridCacheCustomizer.class)
public class ContactInfo implements PortableObject,Serializable{

private static final long serialVersionUID = 1L;

@Column(name = "ADDRESS")
private String address;

@Column(name = "HOMEPHONE")
private String homePhone;

@Column(name = "WORKPHONE")
private String workPhone;

@Column(name = "CELLPHONE")
private String cellPhone;

public String getAddress() {
    return address;
}

public void setAddress(String address) {
    this.address = address;
}

public String getHomePhone() {
    return homePhone;
}

public void setHomePhone(String homePhone) {
    this.homePhone = homePhone;
}

public String getWorkPhone() {
    return workPhone;
}

public void setWorkPhone(String workPhone) {
    this.workPhone = workPhone;
}

public String getCellPhone() {
    return cellPhone;
}

public void setCellPhone(String cellPhone) {
    this.cellPhone = cellPhone;
}

@Override
public void readExternal(PofReader pofReader) throws IOException {
    address = pofReader.readString(1);
    homePhone = pofReader.readString(2);
    workPhone = pofReader.readString(3);
    cellPhone = pofReader.readString(4);
}

@Override
public void writeExternal(PofWriter pofWriter) throws IOException {
    if(address != null) pofWriter.writeString(1, address);
    if(homePhone != null) pofWriter.writeString(2, homePhone);
    if(workPhone != null) pofWriter.writeString(3, workPhone);
    if(cellPhone != null) pofWriter.writeString(4, cellPhone);
}

@Override
public String toString() {
    return "[" 
    + "address = " + address
    + " homePhone = " + homePhone
    + " workPhone = " + workPhone
    + " cellPhone = " + cellPhone
    + "]";
}

}

For the equivalent JQPL

Query query = em.createQuery("SELECT e.conInfo FROM Employee e where e.employId < 3");

worked.

役に立ちましたか?

解決

I tried reproducing this in the latest EclipseLink (a 2.5 nightly) but couldn't. I suspect it might be fixed with criteria API changes to add On support - can you give it a shot to confirm it? You might have to turn off the cache to use the latest version of EclipseLink to test with though.

他のヒント

Check if conInfo is the correct name of your attribute (include your entity code).

Does the equivalent JPQL work?

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top