休眠中复合主键的条件连接查询

Criteria join query for composite primary key in hibernate

需要复合主键的条件连接查询。 实体:

  1. 作品

    @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
    }
    
  2. 用户:

    @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<Role> roles = new HashSet<>();
    
        @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
    }
    
  3. 帐户状态

    @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;
    }
    
  4. 帐号状态道: public class JpaAccountStatesDao 扩展了 JpaDao 实现 AccountStatesDao {

    public JpaAccountStatesDao() {
    super(AccountStates.class);
    }
    
    @Override
    public AccountStates find(Long artOwnerId, Long artworkId, String language) {
    final CriteriaBuilder builder = this.getEntityManager().getCriteriaBuilder();
    final CriteriaQuery<AccountStates> criteriaQuery = builder.createQuery(AccountStates.class);
    
    Root<AccountStates> 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<AccountStates> typedQuery = this.getEntityManager().createQuery(criteriaQuery);
    
    return typedQuery.getSingleResult();
    }
    }
    

我想找到 artOwner id = 1、language = en 和 artwork id = 1 的帐户状态。

任何人都可以建议正确的查询吗?

我找到了相同的解决方案,我尝试传递整个对象而不是对象 ID。

所以最终查询是:

@Override
public AccountStates find(User artOwner, Artwork artwork) {


 final CriteriaBuilder builder = this.getEntityManager().getCriteriaBuilder();
    final CriteriaQuery<AccountStates> criteriaQuery = builder.createQuery(AccountStates.class);

    Root<AccountStates> root = criteriaQuery.from(AccountStates.class);
    Predicate p1 = builder.and(builder.equal(root.get("artwork"), artwork),
            builder.equal(root.get("artOwner"), artOwner));

    criteriaQuery.where(p1);

    TypedQuery<AccountStates> typedQuery = this.getEntityManager().createQuery(criteriaQuery);

    return typedQuery.getSingleResult();
    }
}

现在,它成功运行了...谢谢