0

我有两个对象,都定义为实体,一个包含另一个如下:

@Entity
public class TestC 
{
    @Id @GeneratedValue
    private Integer id;
    @ManyToOne (cascade = {CascadeType.PERSIST, CascadeType.MERGE} )
    TestD d;
} 

@Entity
public class TestD 
{
    @Id @GeneratedValue
    private Integer id;
    String moo;
}    

实体被持久化:

TestC c2 = new TestC();
TestD d2 = new TestD();
d2.moo = "d2";
c2.d = d2;
em.getTransaction().begin();
em.persist(d2);
em.persist(c2);
em.getTransaction().commit();

我正在尝试使用 TestD 的实例查询 TestC 对象:

CriteriaBuilder builder = em.getCriteriaBuilder();
CriteriaQuery<TestC> query = builder.createQuery(TestC.class);
Root<TestC> from = query.from(TestC.class);

ParameterExpression<TestD> pe = builder.parameter(TestD.class);

query.where(builder.equal(pe, from.<TestD>get("d")));

TestC found = em.createQuery(query)
    .setParameter(pe, d2)
    .getSingleResult();

但是EclipseLink在运行查询时会出现以下错误(注意“(?=)”附近的SQL无效,TestD对象没有列名):

Exception in thread "main" Local Exception Stack: 
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.3.2.v20111125-r10461): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLException: Invalid argument value: java.io.NotSerializableException
Error Code: 0
Call: SELECT t1.ID, t1.D_ID FROM TESTD t0, TESTC t1 WHERE ((? = ) AND (t0.ID = t1.D_ID))
bind => [1 parameter bound]
Query: ReadAllQuery(referenceClass=TestC sql="SELECT t1.ID, t1.D_ID FROM TESTD t0, TESTC t1 WHERE ((? = ) AND (t0.ID = t1.D_ID))")

我构建查询错误吗?

谢谢你的帮助!

4

1 回答 1

1

它没有记录在JavaDoc中,但 ParameterExpression 应该是第二个参数。顺序遵循与equal(Expression x, java.lang.Object y)相同的逻辑。此外,您需要.select。EclipseLink(至少 2.3.0)也可以在没有的情况下工作,但根据规范将选择/多选排除在外是不可移植的:

便携式应用程序应该使用 select 或 multiselect 方法来指定查询的选择列表。不使用这些方法之一的应用程序将不可移植。

在这些更改之后,正确的方法是:

CriteriaQuery<TestC> query = builder.createQuery(TestC.class);
Root<TestC> from = query.from(TestC.class);

ParameterExpression<TestD> pe = builder.parameter(TestD.class);
query.select(from)
     .where(builder.equal(from.<TestD>get("d"), pe));

TestC found = em.createQuery(query)
                .setParameter(pe, d)
                .getSingleResult();
于 2012-05-01T15:39:11.310 回答