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

时间:2017-01-04 02:55:21

标签: jpa eclipselink javax.persistence

没有criteriaQuery的手动方法

我已经使用此代码来获取包含Thirdparty的结果集,方法是使用左连接和另一个表ThirdPartyHasOwner,它具有两个主键并且本身就是外键。现在,下面的代码检索正确的结果数据集

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

第三方模特类

/**
 * 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;
        }

    }

第三方的模特类拥有所有者

/**
 * 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;
    }

}

那么我对条件查询做了什么错误还是一些奇怪的错误?

1 个答案:

答案 0 :(得分:0)

虽然日志还不错,但我还是使用了一种不同的方法来提供不同的数据集。

代码之前

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 balance是参数