JPWH book表示使用Hibernate的条件查询中的连接操作会产生带有外键约束的on子句。我在数据库中添加了这些外键约束:
alter table BID add foreign key (BIDDER_ID) references USER (ID)
alter table BID add foreign key (ITEM_ID) REFERENCES ITEM (ID)
alter table ITEM add foreign key (SELLER_ID) REFERENCES ITEM (ID)
所以我期待这个标准查询:
private static void implicitJoin(EntityManager em) {
CriteriaBuilder cb = em.getCriteriaBuilder();
CriteriaQuery criteria = cb.createQuery();
Root<Bid> b = criteria.from(Bid.class);
criteria.select(b).where(
cb.equal(
b.get("item").get("seller").get("username"), "johndoe")
);
TypedQuery<Item> query = em.createQuery(criteria);
List<Item> results = query.getResultList();
}
翻译成:
select b.* from BID b inner join ITEM i on b.ITEM_ID = i.ID inner join
USER u on i.SELLER_ID = u.ID where u.USERNAME = 'johndoe';
但是我得到了这个SQL语句:
/* select generatedAlias0 from Bid as generatedAlias0 where generatedAlias0.item.seller.username=:param0 */ select bid0_.BID_ID as BID_ID1_0_, bid0_.BIDDER_ID as BIDDER_I2_0_, bid0_.ITEM_ID as ITEM_ID3_0_ from BID bid0_ cross join ITEM item1_ cross join USER user2_ where bid0_.ITEM_ID=item1_.id and item1_.SELLER_ID=user2_.id and user2_.username=?
如何将bid0_.ITEM_ID=item1_.id and item1_.SELLER_ID=user2_.id
放入on子句?可能吗?这是实体:
@Entity
@Table(name = "BID")
public class Bid implements Serializable {
@Id @GeneratedValue
@Column(name = "BID_ID")
private Long id = null;
@ManyToOne
@JoinColumn(name = "ITEM_ID", nullable = false, updatable = false, insertable = false)
private Item item;
@ManyToOne
@JoinColumn(name = "BIDDER_ID", nullable = false, updatable = false)
private User bidder;
}
@Entity
@Table(name = "ITEM")
public class Item implements Serializable {
@Id
private Long id = null;
private String name;
@ManyToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "SELLER_ID", nullable = false)
private User seller;
@OneToMany(mappedBy = "item", fetch = FetchType.LAZY)
private List<Bid> bids;
}
@Entity
@Table(name = "USER")
public class User implements Serializable {
@Id
private Long id = null;
private String firstname;
private String lastname;
private String username; // Unique and immutable
}