Reputation: 31
I'm struggling with a very weird behaviour of Hibernate when using Hibernate Criteria API. I'm using hibernate 4.3.6 Final. I got a class AnnouncementAttribute like this:
@Entity
@Table(name = "announcement_attribute")
public class AnnouncementAttribute implements Serializable {
@EmbeddedId
protected AnnouncementAttributePK id;
@Column(name = "attribute_value")
private String attributeValue;
}
and below the AnnouncementAttributePK class:
@Embeddable
public class AnnouncementAttributePK implements Serializable {
@ManyToOne
@JoinColumn(name = "attribute_id")
private Attribute attr;
@ManyToOne
@JoinColumn(name = "announcement_id")
private Announcement announcement;
}
And the Attribute class:
@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;
}
I ommitted getters/ setters here.
Problem is when I try to access @EmbeddedId property attr via Criteria API:
Criteria ac = session().createCriteria(AnnouncementAttribute.class);
ac.add(Restrictions.and(
Restrictions.eq("id.attr.attributeName", "someKey"),
Restrictions.eqOrIsNull("attributeValue", "someValue")));
I'm getting:
org.hibernate.QueryException: could not resolve property: id.attr.attributeName of: com.example.app.domain.AnnouncementAttribute
I already tried to create an alias for embeddedId - still no luck.
Upvotes: 1
Views: 2713
Reputation: 91
A workaround is to add the nested id columns as columns as well with insert and update as false. So you have a read-only mapping of the embeddedId that you can use in criteria without any problems.
Upvotes: 0
Reputation: 31
Well, altough I'm not convinced to the solution I found, I'll post it anyways, maybe someone will find it useful or maybe it will be a good subject for further discussion.
I removed @Embedded from AnnouncementAttributePK
public class AnnouncementAttributePK implements Serializable {
@ManyToOne
@JoinColumn(name = "attribute_id")
private Attribute attr;
@ManyToOne
@JoinColumn(name = "announcement_id")
private Announcement announcement;
}
, then in AnnouncementAttribute I've changed @EmbeddedId to combination of @IdClass and @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;
}
and finally in the Criteria:
Criteria ac = session().createCriteria(AnnouncementAttribute.class)
.createAlias("attr", "atrib");
ac.add(Restrictions.and(
Restrictions.eq("atrib.attributeName", "someKey"),
Restrictions.eqOrIsNull("attributeValue", "someValue")));
After those changes everything works just fine. I got no clue why... I'll further investigate it anyway, because it's at least weird. Maybe it has something to do with a fact that my application is running in Spring Context, using LocalContainerEntityManagerFactoryBean and spring-data-jpa, and a org.hibernate.Session object is obtained by unwraping EntityManager ? :
@PersistenceContext
private EntityManager entityManager;
and session:
private Session session(){
return entityManager.unwrap(Session.class);
}
Upvotes: 1
Reputation: 5371
try
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")));
Upvotes: 0