使用 Criteria 与仅创建查询时的不同结果集

Different Result Set While using Criteria vs just Create Query

没有标准查询的手动方法

我使用此代码通过与另一个 table ThirdPartyHasOwner 的左连接来获取包含 Thirdparty 的结果集,后者具有两个主键并且本身是一个外键。现在下面的代码检索 正确的结果数据集 .

Query query = emManager.createQuery("SELECT c FROM ThirdParty c LEFT JOIN ThirdPartyHasOwner b ON  b.id.third_party_Id = c.id WHERE b.id.ownerId=1");
List<ThirdParty> thirdParties = query.getResultList();

使用条件生成器和条件查询

但是当与条件生成器和查询一起使用时结果集给出了错误的数据集。下面给出了代码因此,为了检查上面的手动查询和条件查询是否给出了相同的查询,我添加了 属性 <property name="eclipselink.logging.level" value="FINE"/> 上面没有条件查询的代码和下面有条件查询的代码都给出了相同的查询代码和控制台结果都在下面给出

    CriteriaBuilder cb = emManager.getCriteriaBuilder();
    CriteriaQuery<ThirdParty> cq = cb.createQuery(ThirdParty.class);
    Root<ThirdParty> a = cq.from(ThirdParty.class);
    Join<ThirdParty, ThirdPartyHasOwner> b = a.join("thirdPartyHasOwners", JoinType.LEFT);

ParameterExpression<Integer> balance = cb.parameter(Integer.class);

Path<Integer> path = b.get("id").get("ownerId");

cq.where(cb.gt(path, balance));

cq.select(a);

TypedQuery<ThirdParty> queryS = emManager.createQuery(cq);

List<ThirdParty> results = queryS.setParameter(balance, 1).getResultList();

控制台结果(第一个用于条件查询第二个 用于 手动方法 )

[EL Fine]: sql: 2017-01-04 06:42:44.026--ServerSession(514728045)--Connection(1288428548)--Thread(Thread[http-bio-8080-exec-3,5,main])--SELECT t1.Id, t1.ADDRESS, t1.CONTACTNO, t1.CREATEDDATE, t1.EMAIL, t1.NAME FROM third_party t1 LEFT OUTER JOIN third_party_has_owner t0 ON (t0.THIRD_PARTY_ID = t1.Id) WHERE (t0.owner_id > ?)
    bind => [1]
[EL Fine]: sql: 2017-01-04 06:48:26.109--ServerSession(514728045)--Connection(1288428548)--Thread(Thread[http-bio-8080-exec-3,5,main])--SELECT t1.Id, t1.ADDRESS, t1.CONTACTNO, t1.CREATEDDATE, t1.EMAIL, t1.NAME FROM third_party t1 LEFT OUTER JOIN third_party_has_owner t0 ON (t0.THIRD_PARTY_ID = t1.Id) WHERE (t0.owner_id = ?)
    bind => [1]

result for both manual and criteria query(结果变量有错误的数据,这是使用条件查询的结果,第三方变量有正确的数据集,这是手动方法的结果)

最后但同样重要的是,我使用的是 javax.persistence.persistence-api,即 eclipselink

This is the overview of the Database tables

型号Class第三方

/**
 * The persistent class for the third_party database table.
 * 
 */
    @Entity
    @Table(name="third_party")
    @NamedQuery(name="ThirdParty.findAll", query="SELECT t FROM ThirdParty t")
    public class ThirdParty implements Serializable {
        private static final long serialVersionUID = 1L;

        @Id
        @GeneratedValue(strategy=GenerationType.IDENTITY)
        @Column(name="Id")
        private int id;

        private String address;

        private String contactNo;

        @Temporal(TemporalType.TIMESTAMP)
        private Date createdDate;

        private String email;

        private String name;

        //bi-directional many-to-one association to ThirdPartyHasOwner
        @OneToMany(mappedBy="thirdParty")
        private List<ThirdPartyHasOwner> thirdPartyHasOwners;

        //bi-directional many-to-one association to ThirdSeatAllocation
        @OneToMany(mappedBy="thirdParty")
        private List<ThirdSeatAllocation> thirdSeatAllocations;

        public ThirdParty() {
        }

        public int getId() {
            return this.id;
        }

        public void setId(int id) {
            this.id = id;
        }

        public String getAddress() {
            return this.address;
        }

        public void setAddress(String address) {
            this.address = address;
        }

        public String getContactNo() {
            return this.contactNo;
        }

        public void setContactNo(String contactNo) {
            this.contactNo = contactNo;
        }

        public Date getCreatedDate() {
            return this.createdDate;
        }

        public void setCreatedDate(Date createdDate) {
            this.createdDate = createdDate;
        }

        public String getEmail() {
            return this.email;
        }

        public void setEmail(String email) {
            this.email = email;
        }

        public String getName() {
            return this.name;
        }

        public void setName(String name) {
            this.name = name;
        }

        public List<ThirdPartyHasOwner> getThirdPartyHasOwners() {
            return this.thirdPartyHasOwners;
        }

        public void setThirdPartyHasOwners(List<ThirdPartyHasOwner> thirdPartyHasOwners) {
            this.thirdPartyHasOwners = thirdPartyHasOwners;
        }

        public ThirdPartyHasOwner addThirdPartyHasOwner(ThirdPartyHasOwner thirdPartyHasOwner) {
            getThirdPartyHasOwners().add(thirdPartyHasOwner);
            thirdPartyHasOwner.setThirdParty(this);

            return thirdPartyHasOwner;
        }

        public ThirdPartyHasOwner removeThirdPartyHasOwner(ThirdPartyHasOwner thirdPartyHasOwner) {
            getThirdPartyHasOwners().remove(thirdPartyHasOwner);
            thirdPartyHasOwner.setThirdParty(null);

            return thirdPartyHasOwner;
        }

        public List<ThirdSeatAllocation> getThirdSeatAllocations() {
            return this.thirdSeatAllocations;
        }

        public void setThirdSeatAllocations(List<ThirdSeatAllocation> thirdSeatAllocations) {
            this.thirdSeatAllocations = thirdSeatAllocations;
        }

        public ThirdSeatAllocation addThirdSeatAllocation(ThirdSeatAllocation thirdSeatAllocation) {
            getThirdSeatAllocations().add(thirdSeatAllocation);
            thirdSeatAllocation.setThirdParty(this);

            return thirdSeatAllocation;
        }

        public ThirdSeatAllocation removeThirdSeatAllocation(ThirdSeatAllocation thirdSeatAllocation) {
            getThirdSeatAllocations().remove(thirdSeatAllocation);
            thirdSeatAllocation.setThirdParty(null);

            return thirdSeatAllocation;
        }

    }

型号Class第三方有所有者

/**
 * The persistent class for the third_party_has_owner database table.
 * 
 */
@Entity
@Table(name="third_party_has_owner")
@NamedQuery(name="ThirdPartyHasOwner.findAll", query="SELECT t FROM ThirdPartyHasOwner t")
public class ThirdPartyHasOwner implements Serializable {
    private static final long serialVersionUID = 1L;

    @EmbeddedId
    private ThirdPartyHasOwnerPK id;

    @Temporal(TemporalType.DATE)
    private Date createdDate;

    //bi-directional many-to-one association to Owner
    @ManyToOne
    private Owner owner;

    //bi-directional many-to-one association to ThirdParty
    @ManyToOne
    @JoinColumn(name="third_party_Id")
    private ThirdParty thirdParty;

    public ThirdPartyHasOwner() {
    }

    public ThirdPartyHasOwnerPK getId() {
        return this.id;
    }

    public void setId(ThirdPartyHasOwnerPK id) {
        this.id = id;
    }

    public Date getCreatedDate() {
        return this.createdDate;
    }

    public void setCreatedDate(Date createdDate) {
        this.createdDate = createdDate;
    }

    public Owner getOwner() {
        return this.owner;
    }

    public void setOwner(Owner owner) {
        this.owner = owner;
    }

    public ThirdParty getThirdParty() {
        return this.thirdParty;
    }

    public void setThirdParty(ThirdParty thirdParty) {
        this.thirdParty = thirdParty;
    }

}

我是不是在条件查询上做错了什么,还是有什么奇怪的错误?

虽然日志很好,但我使用了不同的方法来提供不同的数据集。

编码前

CriteriaBuilder cb = emManager.getCriteriaBuilder();
CriteriaQuery<ThirdParty> cq = cb.createQuery(ThirdParty.class);
Root<ThirdParty> a = cq.from(ThirdParty.class);
Join<ThirdParty, ThirdPartyHasOwner> b = a.join("thirdPartyHasOwners", JoinType.LEFT);

ParameterExpression<Integer> balance = cb.parameter(Integer.class);

Path<Integer> path = b.get("id").get("ownerId");

cq.where(cb.gt(path, balance));

cq.select(a);

TypedQuery<ThirdParty> queryS = emManager.createQuery(cq);

List<ThirdParty> results = queryS.setParameter(balance, 1).getResultList();

代码后

CriteriaBuilder cb = emManager.getCriteriaBuilder();
CriteriaQuery<ThirdParty> cq = cb.createQuery(ThirdParty.class);
Root<ThirdParty> a = cq.from(ThirdParty.class);
Join<ThirdParty, ThirdPartyHasOwner> b = a.join("thirdPartyHasOwners", JoinType.LEFT);

ParameterExpression<Integer> balance = cb.parameter(Integer.class);

cq.where(cb.equal( b.get("id").get("ownerId"),balance));

cq.select(a);

TypedQuery<ThirdParty> queryS = emManager.createQuery(cq);

List<ThirdParty> results = queryS.setParameter(balance, 1).getResultList();

正在更改的代码是 cq.where(cb.gt(path, balance));cq.where(cb.equal( b.get("id").get("ownerId"),balance));,因为此处使用的条件生成器等于 Where b.owner_id = balance 余额是一个参数