EmbeddedId属性上的Hibernate Criteria抛出org.hibernate.QueryException:无法解析属性

时间:2016-01-22 08:12:49

标签: java hibernate hibernate-criteria

在使用Hibernate Criteria API时,我正在努力解决Hibernate非常奇怪的问题。我正在使用hibernate 4.3.6 Final。 我得到了一个类AnnouncementAttribute:

@Entity
@Table(name = "announcement_attribute")
public class AnnouncementAttribute implements Serializable {

    @EmbeddedId
    protected AnnouncementAttributePK id;

    @Column(name = "attribute_value")
    private String attributeValue;
}

并且在AnnouncementAttributePK类之下:

@Embeddable
public class AnnouncementAttributePK implements Serializable {
    @ManyToOne
    @JoinColumn(name = "attribute_id")
    private Attribute attr;

    @ManyToOne
    @JoinColumn(name = "announcement_id")
    private Announcement announcement;
}

属性类:

@Entity
@Table(name = "attribute")
public class Attribute implements Serializable {

    @Id
    @GeneratedValue(strategy = GenerationType.AUTO)
    private Long id;

    @Column(name = "attribute_type")
    private Integer attributeType;

    @Column(name = "attribute_name")
    private String attributeName;
}

我在这里省略了getters / setters。

当我尝试通过Criteria API访问@EmbeddedId属性attr时出现问题:

Criteria ac = session().createCriteria(AnnouncementAttribute.class);
ac.add(Restrictions.and(
                    Restrictions.eq("id.attr.attributeName", "someKey"), 
                    Restrictions.eqOrIsNull("attributeValue", "someValue")));

我得到了:

  

org.hibernate.QueryException:无法解析属性:id.attr.attributeName:com.example.app.domain.AnnouncementAttribute

我已经尝试为embeddedId创建一个别名 - 仍然没有运气。

3 个答案:

答案 0 :(得分:1)

嗯,尽管我不相信我找到的解决方案,但我会发布它,也许有人会发现它很有用,或者它可能是一个很好的主题,可以进一步讨论。

我从AnnouncementAttributePK

中删除了@Embedded
public class AnnouncementAttributePK implements Serializable {
    @ManyToOne
    @JoinColumn(name = "attribute_id")
    private Attribute attr;

    @ManyToOne
    @JoinColumn(name = "announcement_id")
    private Announcement announcement;
}

,然后在AnnouncementAttribute中我将@EmbeddedId更改为@IdClass和@Id的组合:

@Entity
@Table(name = "announcement_attribute")
@IdClass(AnnouncementAttributePK.class)
public class AnnouncementAttribute implements Serializable {

    @Id
    private Attribute attr;
    @Id
    private Announcement announcement;

    @Column(name = "attribute_value")
    private String attributeValue;
}

最后在标准中:

Criteria ac = session().createCriteria(AnnouncementAttribute.class)
            .createAlias("attr", "atrib");
ac.add(Restrictions.and(
                    Restrictions.eq("atrib.attributeName", "someKey"), 
                    Restrictions.eqOrIsNull("attributeValue", "someValue")));

在这些改变之后一切正常。我不知道为什么......无论如何我会进一步调查它,因为它至少很奇怪。也许它与我的应用程序在Spring Context中运行的事实有关,使用LocalContainerEntityManagerFactoryBean和spring-data-jpa,并且通过解开EntityManager来获取org.hibernate.Session对象? :

@PersistenceContext
private EntityManager entityManager;

和会话:

private Session session(){
    return entityManager.unwrap(Session.class);
}

答案 1 :(得分:0)

Criteria ac = session().createCriteria(AnnouncementAttribute.class)
.createAlias("id", "id")
.createAlias("id.attr", "idAttr")
.add(Restrictions.and(
                    Restrictions.eq("idAttr.attributeName", "someKey"), 
                    Restrictions.eqOrIsNull("attributeValue", "someValue")));

答案 2 :(得分:0)

一种解决方法是将嵌套id列添加为列,并将insert和update添加为false。因此,您具有EmbeddedId的只读映射,可以在条件中使用它,而不会出现任何问题。