Hibernate:无法针对非常简单的对象层次结构解析路径的属性

时间:2011-08-21 15:20:57

标签: java hibernate jpa

任何人都有任何想法为什么hibernate v3.6.7下面看似简单的类层次结构有问题?

@Entity
public class X implements Serializable {
    @Id
    String id;

    X() {

    }

    public X(String id) {
        this.id = id;
    }
}

interface PK {
    Object getPK();
}

@Entity
public class Y  implements Serializable, PK {
    @Id
    @OneToOne
    @JoinColumn(name ="id")
    X x;

    protected Y() {

    }

    public Y(X x) {
        this.x = x;
    }

    @Override
    public Object getPK() {
        return x.id;
    }
}

private static final EntityManager em;
private final CriteriaBuilder cb = em.getCriteriaBuilder();
private final CriteriaQuery<Y> query = cb.createQuery(Y.class);
private final Root<Y> entity = query.from(Y.class);

static {
    Map<String, Object> properties = new HashMap<String, Object>();
        // initialise properties appropriately
    EntityManagerFactory emf =
        Persistence.createEntityManagerFactory("myPersistenceUnit", properties);
    em = emf.createEntityManager();

}

@Test
public void simpleTest() {
    X x1 = new X("X1");
    X x2 = new X("X1");
    List<Y> yy = new ArrayList<Y>();

    Y yX1 = new Y(x1);
    yy.add(yX1);

    Y yX2 = new Y(x2);
    yy.add(yX2);

    saveItems(yy);

    String name = "x";
    Path<Object> path = entity.get(name);
    Predicate restriction = cb.conjunction();
    restriction = cb.and(restriction, cb.and(new Predicate[]{cb.equal(path, x1)}));

    TypedQuery<Y> tq = em.createQuery(this.query);
    Y result = null;

    try {
        result = tq.getSingleResult();
    } catch (NoResultException e) {
    }

    assertNotNull(result);
}

尝试执行此测试会引发以下异常:

java.lang.IllegalArgumentException: Unable to resolve attribute [x] against path
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.unknownAttribute(AbstractPathImpl.java:118)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.locateAttribute(AbstractPathImpl.java:223)
    at org.hibernate.ejb.criteria.path.AbstractPathImpl.get(AbstractPathImpl.java:194)
    at com.example.entity.impl.MyPersistenceTest.simpleTest(MyPersistenceTest.java:212)

3 个答案:

答案 0 :(得分:0)

这是什么?

X() {

}

我认为应该有一个空的构造函数!

public X(String id) {
    this.id = id;
}

为什么在类上使用@id注释 - &gt; X 我认为像id这样的生成值必须很长!

答案 1 :(得分:0)

请注意问题是什么,但要注意的事项:

  • 您不应该使用其他实体和@Id。我不确定这是否可行。使用Embeddable@IdClass
  • 为字段提供getter和setter。

答案 2 :(得分:0)

我觉得映射有点不对劲。

首先,X缺少@Embeddable,Y.x应该映射为@EmbeddedId,而不是@Id

扩展Bozho说,如果你想将一个类用作ID和Entity,你需要使用映射注释创建每个用法(PK和实体)的超类和一个子类。