Hi there,
I'm having some trouble with a Criteria query. It seems that the generated SQL query misses a join. I have a many-to-many relationship between item (Articolo) and author (Autore). The
n-m table have the foreign key column plus a couple of attributes of the relationship (type of relationship and ordering column). To be able to access this extra info I created a pojo to manage it. Everything works fine, but when i add an ordering to the critieria, it generates a wrong SQL.
I'm using hibernate 3.5.0-Final.
Here's my schema (I'll omit some attributes for brevity):
ItemCode:
@Entity
@Table( name = "ARTICOLO" )
public class Articolo implements Serializable {
private String id;
...
private List<ArticoloAutore> articoloAutoreList;
@Id
@Column( name = "ID" )
public String getId() {
return this.id;
}
public void setId(String id) {
this.id = id;
}
...
@OneToMany()
@JoinColumn( name = "ARTICOLOID" )
@OrderBy("posizione")
public List<ArticoloAutore> getArticoloAutoreList() {
return articoloAutoreList;
}
public void setArticoloAutoreList( List<ArticoloAutore> articoloAutoreList ) {
this.articoloAutoreList = articoloAutoreList;
}
}
AuthorCode:
@Entity
@Table( name = "AUTORE" )
public class Autore implements Serializable {
private long id;
...
private List<ArticoloAutore> articoloAutoreList;
@Id
@Column( name = "ID" )
public long getId() {
return this.id;
}
public void setId(long id) {
this.id = id;
}
...
@OneToMany()
@JoinColumn( name = "ARTICOLOID" )
public List<ArticoloAutore> getArticoloAutoreList() {
return articoloAutoreList;
}
public void setArticoloAutoreList( List<ArticoloAutore> articoloAutoreList ) {
this.articoloAutoreList = articoloAutoreList;
}
}
RelationCode:
@Entity
@Table( name = "ARTICOLO_AUTORE" )
public class ArticoloAutore {
private ArticoloAutorePK id;
private Integer tipo;
private Integer posizione;
public static final int TIPO_AUTORE = 1;
public static final int TIPO_CURATORE = 2;
public static final int TIPO_TRADUTTORE = 3;
public static final int TIPO_ILLUSTRATORE = 4;
public ArticoloAutore() {
}
public ArticoloAutore( ArticoloAutorePK id, Integer tipo, Integer posizione ) {
this.id = id;
this.tipo = tipo;
this.posizione = posizione;
}
@EmbeddedId
public ArticoloAutorePK getId() {
return id;
}
public void setId( ArticoloAutorePK id ) {
this.id = id;
}
@Column( name = "TIPO" )
public Integer getTipo() {
return tipo;
}
public void setTipo( Integer tipo ) {
this.tipo = tipo;
}
@Column( name = "POSIZIONE" )
public Integer getPosizione() {
return posizione;
}
public void setPosizione( Integer posizione ) {
this.posizione = posizione;
}
}
Composite-idCode:
@Embeddable
public class ArticoloAutorePK implements Serializable {
private Articolo articolo;
private Autore autore;
/** full constructor */
public ArticoloAutorePK(Articolo articolo, Autore autore) {
this.articolo = articolo;
this.autore = autore;
}
/** default constructor */
public ArticoloAutorePK() {
}
@ManyToOne
@JoinColumn( name = "ARTICOLOID", nullable = false )
public Articolo getArticolo() {
return articolo;
}
public void setArticolo( Articolo articolo ) {
this.articolo = articolo;
}
@ManyToOne
@JoinColumn( name = "AUTOREID", nullable = false )
public Autore getAutore() {
return autore;
}
public void setAutore( Autore autore ) {
this.autore = autore;
}
}
Here's the Criteria query:
Code:
Criteria criteria = session.createCriteria( ArticoloAutore.class, "a" );
criteria = criteria.createAlias( "a.id.autore", "u" );
criteria = criteria.add( Restrictions.eq( "u.id", autoreId ) );
criteria.addOrder( org.hibernate.criterion.Order.asc( "u.posizione" ) );
criteria.list();
Here's the generated query:
Code:
select this_.ARTICOLOID as ARTICOLOID64_0_, this_.AUTOREID as AUTOREID64_0_, this_.POSIZIONE as POSIZIONE64_0
_, this_.TIPO as TIPO64_0_ from ARTICOLO_AUTORE this_ where u1_.ID=? order by u1_.POSIZIONE asc
The join with AUTORE is missing, but it's using the alias in the order by clause, causing an error.
I've also tried without the alias:
Code:
Criteria criteria = session.createCriteria( ArticoloAutore.class, "a" );
criteria = criteria.add( Restrictions.eq( "a.id.autore.id", autoreId ) );
criteria.addOrder( org.hibernate.criterion.Order.asc( "a.id.autore.posizione" ) );
criteria.list();
But this time I got an Hibernate exception:
Code:
org.hibernate.QueryException: could not resolve property: id.autore.posizione of: ejb.model.ArticoloAutore
at org.hibernate.persister.entity.AbstractPropertyMapping.propertyException(AbstractPropertyMapping.java:81)
at org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:96)
at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:62)
at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1443)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumns(CriteriaQueryTranslator.java:483)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getColumnsUsingProjection(CriteriaQueryTranslator.java:
443)
at org.hibernate.criterion.Order.toSqlString(Order.java:68)
at org.hibernate.loader.criteria.CriteriaQueryTranslator.getOrderBy(CriteriaQueryTranslator.java:394)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:114)
at org.hibernate.loader.criteria.CriteriaJoinWalker.<init>(CriteriaJoinWalker.java:83)
at org.hibernate.loader.criteria.CriteriaLoader.<init>(CriteriaLoader.java:92)
at org.hibernate.impl.SessionImpl.list(SessionImpl.java:1687)
Can someone help me to find what I'm doing wrong?
TIA