Tôi có truy vấn sau đây và phương phápHibernate HQL tham gia Truy xuất không đệ quy lấy
private static final String FIND = "SELECT DISTINCT domain FROM Domain domain LEFT OUTER JOIN FETCH domain.operators LEFT OUTER JOIN FETCH domain.networkCodes WHERE domain.domainId = :domainId";
@Override
public Domain find(Long domainId) {
Query query = getCurrentSession().createQuery(FIND);
query.setLong("domainId", domainId);
return (Domain) query.uniqueResult();
}
Với Domain
như
@Entity
@Table
public class Domain {
@Id
@GenericGenerator(name = "generator", strategy = "increment")
@GeneratedValue(generator = "generator")
@Column(name = "domain_id")
private Long domainId;
@Column(nullable = false, unique = true)
@NotNull
private String name;
@Column(nullable = false)
@NotNull
@Enumerated(EnumType.STRING)
private DomainType type;
@OneToMany(cascade = {
CascadeType.PERSIST,
CascadeType.MERGE
}, fetch = FetchType.EAGER)
@JoinTable(joinColumns = {
@JoinColumn(name = "domain_id")
}, inverseJoinColumns = {
@JoinColumn(name = "code")
})
@NotEmpty
@Valid // needed to recur because we specify network codes when creating the domain
private Set<NetworkCode> networkCodes = new HashSet<>();
@ManyToMany(fetch = FetchType.EAGER)
@JoinTable(joinColumns = {
@JoinColumn(name = "parent", referencedColumnName = "domain_id")
}, inverseJoinColumns = {
@JoinColumn(name = "child", referencedColumnName = "domain_id")
})
private Set<Domain> operators = new HashSet<>();
// more
}
Tôi mong chờ truy vấn duy nhất này để lấy Set<NetworkCode>
và Set<Domain
> mối quan hệ, nhưng nó không. Nói rằng Domain
tôi truy vấn có hai nhà khai thác, Hibernate sẽ thực hiện 1 + 2 * 2 = 5 truy vấn
Hibernate: select distinct domain0_.domain_id as domain1_1_0_, domain2_.domain_id as domain1_1_1_, networkcod4_.code as code2_2_, domain0_.name as name1_0_, domain0_.type as type1_0_, domain2_.name as name1_1_, domain2_.type as type1_1_, operators1_.parent as parent1_0__, operators1_.child as child4_0__, networkcod3_.domain_id as domain1_1_1__, networkcod3_.code as code5_1__ from domain domain0_ left outer join domain_operators operators1_ on domain0_.domain_id=operators1_.parent left outer join domain domain2_ on operators1_.child=domain2_.domain_id inner join domain_network_codes networkcod3_ on domain0_.domain_id=networkcod3_.domain_id inner join network_code networkcod4_ on networkcod3_.code=networkcod4_.code where domain0_.domain_id=?
Hibernate: select operators0_.parent as parent1_1_, operators0_.child as child4_1_, domain1_.domain_id as domain1_1_0_, domain1_.name as name1_0_, domain1_.type as type1_0_ from domain_operators operators0_ inner join domain domain1_ on operators0_.child=domain1_.domain_id where operators0_.parent=?
Hibernate: select networkcod0_.domain_id as domain1_1_1_, networkcod0_.code as code5_1_, networkcod1_.code as code2_0_ from domain_network_codes networkcod0_ inner join network_code networkcod1_ on networkcod0_.code=networkcod1_.code where networkcod0_.domain_id=?
Hibernate: select operators0_.parent as parent1_1_, operators0_.child as child4_1_, domain1_.domain_id as domain1_1_0_, domain1_.name as name1_0_, domain1_.type as type1_0_ from domain_operators operators0_ inner join domain domain1_ on operators0_.child=domain1_.domain_id where operators0_.parent=?
Hibernate: select networkcod0_.domain_id as domain1_1_1_, networkcod0_.code as code5_1_, networkcod1_.code as code2_0_ from domain_network_codes networkcod0_ inner join network_code networkcod1_ on networkcod0_.code=networkcod1_.code where networkcod0_.domain_id=?
Tôi đoán đây là bởi vì tôi đang tham gia các nhà khai thác Domain
yếu tố nhưng họ phải tham gia vào bản thân. Có một truy vấn HQL tôi có thể thực hiện mà sẽ làm cả hai?
Các bộ sưu tập đó cần phải là 'EAGER' để chúng được khởi tạo trong giới hạn' Giao dịch' của tôi. Tôi sử dụng chúng trong lớp xem của tôi. Tôi tự hỏi nếu nó có thể tải tất cả các nhà khai thác/networkcodes trong một swoop, thay vì một truy vấn cho mỗi 'Domain'. –
Không phải không sử dụng SQL độc quyền (xem http://docs.oracle.com/cd/B19306_01/server.102/b14200/queries003.htm chẳng hạn), hoặc không điều chỉnh mô hình của bạn để giới thiệu, ví dụ: gốc của cây trong mỗi nút con và tải tất cả các tên miền có cùng một nút gốc. Bạn không thể đơn giản làm mọi thứ lười biếng và sử dụng OpenSessionInView? Làm cho hiệp hội tomany háo hức gần như luôn luôn là một ý tưởng tồi, đặc biệt là nếu đệ quy: điều này làm cho nó háo hức ** mỗi ** trường hợp sử dụng, bao gồm cả những người chỉ cần tải một thực thể cụ thể. –
Vấn đề không phải là tải chậm. Tất cả dữ liệu đó sẽ được truy xuất bất kể. Tôi chỉ không muốn gửi tấn yêu cầu SQL. Tôi sẽ xem xét cẩn thận tài liệu bạn đã liên kết. Cấp cho nó vài ngày. Cảm ơn bạn. –