title: Criteria join query for composite primary key in hibernate
body: <p>Need criteria join query for a composite primary key.
  Entities:</p>
  
  <ol>
  <li><p>ArtWork</p>
  
  <pre><code>@Entity
  @Table(name = "artwork")
  public class ArtWork implements io.malevich.web.entity.Entity {
  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  @Id
  @Column(name = "language", columnDefinition = "CHAR(2)")
  private String language;
  @Column(name = "art_name", nullable = false)
  private String artName;
  @Column(name = "creation_date", nullable = false)
  private Date creationDate;
  @Column(name = "edition_flag", nullable = false, columnDefinition = "tinyint(1)")
  private boolean editionFlag;
  @Column(name = "replica_flag", nullable = false, columnDefinition = "tinyint(1)")
  private boolean replicaFlag;
  @Column(name = "number_of_editions")
  private Long numberOfEditions;
  @Column(name = "original_id")
  private Long originalId;
  
  @ManyToOne
  @JoinColumns({
          @JoinColumn(
                  name = "category_id",
                  referencedColumnName = "id", insertable = false, updatable = false),
          @JoinColumn(
                  name = "language",
                  referencedColumnName = "language", insertable = false, updatable = false)
  })
  private Category category;
  
  @ManyToOne
  @JoinColumns({
          @JoinColumn(
                  name = "gallery_id",
                  referencedColumnName = "id", insertable = false, updatable = false),
          @JoinColumn(
                  name = "language",
                  referencedColumnName = "language", insertable = false, updatable = false)
  })
  private Gallery gallery;
  
  @ManyToOne
  private Specialization specialization;
  
  @ManyToOne
  @JoinColumns({
          @JoinColumn(
                  name = "author_id",
                  referencedColumnName = "id", insertable = false, updatable = false),
          @JoinColumn(
                  name = "language",
                  referencedColumnName = "language", insertable = false, updatable = false)
  })
  private Author author;
  
  @Column
  private String description;
  @Column
  private Double price;
  
  //getter setter
  }
  </code></pre></li>
  <li><p>User:</p>
  
  <pre><code>@javax.persistence.Entity
  @Table(name = "user")
  public class User implements Entity, UserDetails {
      @Id
      @GeneratedValue(strategy = GenerationType.IDENTITY)
      private Long id;
  
      @Column(unique = true, length = 255, nullable = false)
      private String name;
  
      @Column(length = 255, nullable = false)
      private String password;
  
      @ElementCollection(fetch = FetchType.EAGER)
      private Set&lt;Role&gt; roles = new HashSet&lt;&gt;();
  
      @Column(name = "user_type_id")
      private Long userTypeId;
  
      @ManyToOne
      @JoinColumn(name = "person_id", referencedColumnName = "id")
      private Person person;
  
      @ManyToOne
      @JoinColumn(name = "organization_id", referencedColumnName = "id")
      private Organization organization;
  
      @ManyToOne
      @JoinColumn(name = "file_id", referencedColumnName = "id")
      private File file;
  
  
      @Column(name = "activity_flag")
      private boolean activityFlag;
  //gettter and setter
  }
  </code></pre></li>
  <li><p>Account States</p>
  
  <pre><code>@javax.persistence.Entity
  @Table(name = "account_states")
  public class AccountStates implements Entity {
  
  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  private Long id;
  
  @Column(insertable = false, updatable = false)
  private String language;
  
  @ManyToOne
  @JoinColumns({ @JoinColumn(name = "artwork_id", referencedColumnName = "id"),
          @JoinColumn(name = "language", referencedColumnName = "language") })
  private ArtWork artwork;
  
  @ManyToOne
  @JoinColumn(name = "art_owner_id", referencedColumnName = "id")
  private User artOwner;
  
  @Column(name = "quantity")
  private Long quantity;
  
  @Temporal(TemporalType.DATE)
  @Column(name = "buy_date")
  private Date buyDate;
  }
  </code></pre></li>
  <li><p>Account State Dao:
      public class JpaAccountStatesDao extends JpaDao 
      implements AccountStatesDao {</p>
  
  <pre><code>public JpaAccountStatesDao() {
  super(AccountStates.class);
  }
  
  @Override
  public AccountStates find(Long artOwnerId, Long artworkId, String language) {
  final CriteriaBuilder builder = this.getEntityManager().getCriteriaBuilder();
  final CriteriaQuery&lt;AccountStates&gt; criteriaQuery = builder.createQuery(AccountStates.class);
  
  Root&lt;AccountStates&gt; root = criteriaQuery.from(AccountStates.class);
  Predicate p1 = builder.and(builder.equal(root.get("artwork"), artworkId),
          builder.equal(root.get("artwork"), language), builder.equal(root.get("artOwner"), artOwnerId));
  
  criteriaQuery.where(p1);
  
  TypedQuery&lt;AccountStates&gt; typedQuery = this.getEntityManager().createQuery(criteriaQuery);
  
  return typedQuery.getSingleResult();
  }
  }
  </code></pre></li>
  </ol>
  
  <p>I want to find Account States where artOwner id = 1 and language = en and artwork id = 1.</p>
  
  <p>Can anyone suggest proper query for the same?</p>