I have three entities: Account, AccountAttribut and Attribut. Account and Attribut are associated via AccountAttribut in a many-to-many relationship like it is described [1].
The question is: Why cant i use: "aa_pk.attribut" as a property name to navigate through the association tree? Because this is the property name, i defined in my AccountAttribut entity, isnt it?
Can you help me with this issue?
[1]: http://giannigar.wordpress.com/2009/09/04/mapping-a-many-to-many-join-table-with-extra-column-using-jpa/ "Mapping a many-to-many join table with extra column using JPA"
These are relevant code extracts:
Account:    
Code:
@Entity
    @Table(name = "account")
    public class Account {
       
       private Long accountId;
       private List<AccountAttribut> accountAttributes = new LinkedList<AccountAttribut>();
       private Person person;
       private Zielsystem zielsystem;
    
       public Account() {
       }
        // ...
    }
AccountAttribut:    
Code:
@Entity
    @Table(name="account_attribut")
    @AssociationOverrides({
       @AssociationOverride(name="aa_pk.account", joinColumns = @JoinColumn(name="account_id")),
       @AssociationOverride(name="aa_pk.attribut", joinColumns = @JoinColumn(name="attribut_id"))
    })
    public class AccountAttribut {}
   private AccountAttributPk aa_pk = new AccountAttributPk();
   
   @Column(name="wert")
   private String wert;
   @EmbeddedId
   public AccountAttributPk getAa_pk() {
      return aa_pk;
   }
   public void setAa_pk(AccountAttributPk aa_pk) {
      this.aa_pk = aa_pk;
   }
   @Transient
   public Account getAccount() {
      return getAa_pk().getAccount();
   }
   
   public void setAccount(Account account) {
      getAa_pk().setAccount(account);
   }
   
   @Transient
   public Attribut getAttribut() {
      return getAa_pk().getAttribut();
   }
   
   public void setAttribut(Attribut attribut) {
      getAa_pk().setAttribut(attribut);
   }
   
   public String getWert() {
      return wert;
   }
   public void setWert(String wert) {
      this.wert = wert;
   }
   
   public boolean equals(Object o) {
       if (this== o) return true;
       if (o ==null|| getClass() != o.getClass()) return false;
        
       AccountAttribut that = (AccountAttribut) o;
        
       if (getAa_pk() !=null?!getAa_pk().equals(that.getAa_pk()) : that.getAa_pk() !=null) return false;
        
       return true;
   }
   
    public int hashCode() {
       return (getAa_pk() !=null? getAa_pk().hashCode() : 0);
    }
    }
AccountAttributPk:    
Code:
public class AccountAttributPk implements Serializable {
    
       private static final long serialVersionUID = -1551814445010872872L;
       private Account account;
       private Attribut attribut;
    
       @ManyToOne
       public Account getAccount() {
          return account;
       }
    
       public void setAccount(Account account) {
          this.account = account;
       }
       
       @ManyToOne
       public Attribut getAttribut() {
          return attribut;
       }
    
       public void setAttribut(Attribut attribut) {
          this.attribut = attribut;
       }
       
       public boolean equals(Object o) {
          if (this == o)
             return true;
          if (o == null || getClass() != o.getClass())
             return false;
    
          AccountAttributPk that = (AccountAttributPk) o;
    
          if (account != null ? !account.equals(that.account) : that.account != null)
             return false;
          if (attribut != null ? !attribut.equals(that.attribut)
                : that.attribut != null)
             return false;
    
          return true;
       }
    
       public int hashCode() {
          int result;
          result = (account != null ? account.hashCode() : 0);
          result = 31 * result + (attribut != null ? attribut.hashCode() : 0);
          return result;
       }
    }
The CriteriaQuery:    
Code:
List<Account> queried_accounts = HibernateUtils.criteriaList(
       session.createCriteria(Account.class).
          createCriteria("accountAttribute").
             createCriteria("aa_pk.attribut").
                add(Restrictions.isNotNull("name"))
    );
The Exception:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
	at org.hibernate.exception.internal.SQLExceptionTypeDelegate.convert(SQLExceptionTypeDelegate.java:80)
	at org.hibernate.exception.internal.StandardSQLExceptionConverter.convert(StandardSQLExceptionConverter.java:49)
I tried the following solutions from a proposed solution in Stackoverflow:
(Solution 1)
Code:
    List<Account> queried_accounts = HibernateUtils.criteriaList(
       session.createCriteria(Account.class).
          createCriteria("accountAttributes","accAttrAlias").
           createCriteria("accAttrAlias.aa_pk","accAttrAAPKAlias").
             createCriteria("accAttrAAPKAlias.attribut", "attrAlias").
                add(Restrictions.isNotNull("attrAlias.name"))
    );
Java Errorlog:
org.hibernate.QueryException: Criteria objects cannot be created directly on components.  Create a criteria on owning entity and use a dotted property to access component property: accountAttributes.aa_pk
(Solution 2)
Code:
    List<Account> queried_accounts = HibernateUtils.criteriaList(
       session.createCriteria(Account.class).
          createCriteria("accountAttributes","accAttrAlias").
             createCriteria("accAttrAlias.aa_pk.attribut", "attrAlias").
                add(Restrictions.isNotNull("attrAlias.name"))
    );
Java Errorlog:
org.hibernate.exception.SQLGrammarException: could not extract ResultSet
Hibernate Errorlog:
"Hibernate: select this_.account_id as account_1_3_4_, this_.person_id as person_i2_3_4_, this_.zielsystem_id as zielsyst3_3_4_, accattrali1_.account_id as account_3_4_0_, accattrali1_.attribut_id as attribut2_4_0_, accattrali1_.wert as wert1_4_0_, person5_.person_id as person_i1_2_1_, personenat6_.person_id as person_i3_2_6_, personenat6_.attribut_id as attribut2_8_6_, personenat6_.person_id as person_i3_8_6_, personenat6_.attribut_id as attribut2_8_2_, personenat6_.person_id as person_i3_8_2_, personenat6_.wert as wert1_8_2_, zielsystem7_.zielsystem_id as zielsyst1_9_3_, zielsystem7_.name as name2_9_3_ from account this_ inner join account_attribut accattrali1_ on this_.account_id=accattrali1_.account_id left outer join PERSON person5_ on this_.person_id=person5_.person_id left outer join person_attribut personenat6_ on person5_.person_id=personenat6_.person_id left outer join zielsystem zielsystem7_ on this_.zielsystem_id=zielsystem7_.zielsystem_id where attralias2_.name is not null
Feb 20, 2014 11:25:11 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
WARN: SQL Error: 1054, SQLState: 42S22
Feb 20, 2014 11:25:11 PM org.hibernate.engine.jdbc.spi.SqlExceptionHelper logExceptions
ERROR: Unknown column 'attralias2_.name' in 'where clause'"