我使用Spring Data JPA + Hibernate作爲webapp。對於特定的域模型A,我們在另一個域B中有一對多關聯。這樣A將有一個Set getB(),B將有一個getA()。JPA雙向1..N關聯,避免在子查詢中設置父項
查詢A圖時,我看到hibernate使用1 + n查詢。用於獲取A圖的單個外連接查詢,然後在每個B中設置A的'n'查詢。
我在這裏是否缺少任何模式?既然所有的孩子都有同一個父母,是不是可以避免這些'n'查詢呢?
@MappedSuperclass
@Data
public abstract class Batch implements Serializable {
private static final long serialVersionUID = 1L;
@OneToOne(fetch = FetchType.EAGER)
@JoinColumn(name = "batch_id", referencedColumnName = "batch_id")
protected BatchID batchId;
}
/*
//The parent class in a simplified form
*/
@Entity
@Table(name = "DRYRUN")
@Inheritance(strategy=InheritanceType.TABLE_PER_CLASS)
public class DryrunBatch extends Batch {
/**
*
*/
private static final long serialVersionUID = -1596595930859735318L;
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@[email protected]
protected Long id;
public DryrunTNStatus newTNStatus()
{
final DryrunTNStatus tn = new DryrunTNStatus();
tn.setBatch(this);
getTnStatus().add(tn);
return tn;
}
@OneToMany(fetch = FetchType.LAZY, mappedBy = "batch")
@[email protected]
private Set tnStatus = new HashSet();
}
//The child class in a simplified form
@Entity
@Table(name = "DRYRUN_TN_STATUS")
@Data
public class DryrunTNStatus implements Serializable{
/**
*
*/
private static final long serialVersionUID = -4388406636444350023L;
public DryrunTNStatus(String accountNo, String telNo) {
super();
this.accountNo = accountNo;
this.telNo = telNo;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "BATCH_ID", referencedColumnName = "BATCH_ID")
private DryrunBatch batch;
public DryrunTNStatus()
{
}
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
protected Long id;
}
使用JpaRepository獲取對象圖的代碼。使用Spring JPA支持來執行外部聯接。我更喜歡Hibernate的@Fetch註釋。
DryrunBatch drBatch = drBatchRepo.findOne(new Specification() {
@Override
public Predicate toPredicate(Root root, CriteriaQuery query,
CriteriaBuilder cb) {
query.distinct(true);
root.fetch("tnStatus", JoinType.LEFT);
return cb.equal(root.get("batchId").get("id"),
batch.getId());
}
});
最後從日誌中查詢hibernate。我運行一個junit,從DB獲取10個孩子的父母。
//this query can fetch data for the complete graph??
Hibernate: select distinct dryrunbatc0_.id as id1_6_0_, tnstatus1_.id as id1_9_1_[etc..] from dryrun dryrunbatc0_ left outer join dryrun_tn_status tnstatus1_ on dryrunbatc0_.batch_id=tnstatus1_.batch_id where dryrunbatc0_.batch_id=15
//and then 10 queries like
Hibernate: select dryrunbatc0_.id as id1_6_3_, [etc..] from dryrun dryrunbatc0_ left outer join batch_id batchid1_ on dryrunbatc0_.batch_id=batchid1_.batch_id inner join users user2_ on dryrunbatc0_.created_by=user2_.login_id left outer join dryrun_tn_status tnstatus3_ on dryrunbatc0_.batch_id=tnstatus3_.batch_id where dryrunbatc0_.batch_id=?
您是否嘗試過FetchMode https://www.google.de/search?q=hibernate+%40Fetch%28FetchMode.SELECT%29&ie=utf-8&oe=utf-8&gws_rd=cr&ei=iyseVtKDGIX4ULi5vagD – HRgiger
@HRgiger是的,我試過JOIN ,SUBSELECT也是如此。沒有任何區別。 –