在使用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创建一个别名 - 仍然没有运气。
答案 0 :(得分:1)
嗯,尽管我不相信我找到的解决方案,但我会发布它,也许有人会发现它很有用,或者它可能是一个很好的主题,可以进一步讨论。
我从AnnouncementAttributePK
中删除了@Embeddedpublic 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的只读映射,可以在条件中使用它,而不会出现任何问题。