我有一个应用程序,我正在使用Hibernate和JPA。我有2个对象(订单和产品)。他们加在一起,我可以获得我想要的信息,但它实际发出1个查询来获取我的所有订单,我在我的日志中收到一堆查询以查找产品信息。我尝试了各种注释,但无法使其正常工作。任何帮助都会很棒。
这是我的代码:
import org.apache.commons.lang3.StringUtils;
import org.apache.commons.lang3.builder.EqualsBuilder;
import org.apache.commons.lang3.builder.ToStringBuilder;
import org.hibernate.annotations.NotFound;
import org.hibernate.annotations.NotFoundAction;
import javax.persistence.*;
@Entity
public class ProductFeedback implements ProductFeedbackInterface {
@Id
@GeneratedValue(strategy = GenerationType.AUTO)
@Column(columnDefinition="INT")
private Long id;
private String decision;
private String reportId;
...
@ManyToOne
@NotFound(action = NotFoundAction.IGNORE)
@JoinColumn(name = "sku", referencedColumnName = "sku", insertable = false, updatable = false)
public Product product;
当我尝试查询此表时,我会得到类似以下查询的信息:
Hibernate: select top 50 productfee0_.id as id1_1_... from product_feedback productfee0_ where 1=1 and productfee0_.date_reported_date>=? and productfee0_.date_reported_date<=? and (productfee0_.decision=? or productfee0_.decision is null) and (productfee0_.dtype=? or productfee0_.dtype=?) and (productfee0_.severity in (0) or productfee0_.dtype<>?) order by productfee0_.date_reported_date desc
Hibernate: select ... from product product0_ where product0_.sku=?
Hibernate: select ... from product product0_ where product0_.sku=?
编辑:::我也试过使用@Fetch(FetchMode.JOIN)也没有运气。
有什么想法吗?
编辑:
我们正在使用规范来构建查询:
public List<ProductFeedback> findAll(ProductFeedbackFilters productFeedbackFilters) {
Page recordsPage = jpaRecordRepository.findAll(buildSpecifications(productFeedbackFilters), sortPageable(productFeedbackFilters.getLimit()));
return recordsPage.getContent();
}
以下是一个示例......
private Specifications<ProductFeedback> defaultSpecifications() {
return where((queryRoot, query, criteriaBuilder) -> {
return criteriaBuilder.and(new Predicate[]{}); // Always true
});
}
private Specification<ProductFeedback> buildSpecifications(ProductFeedbackFilters filters) {
return new RecordSpecificationsBuilder(filters)
.onOrAfterStartDate()
.onOrBeforeEndDate()
.status()
.type()
.userQuery()
.severity()
.keyword()
.build();
}
public ProductFeedback findByReturnIdentifier(Integer catalogNumber, String commentType) {
return jpaRecordRepository.findOne((queryRoot, query, criteriaBuilder) ->
criteriaBuilder.and(criteriaBuilder.equal(queryRoot.get("catalogNumber"), catalogNumber), criteriaBuilder.equal(queryRoot.get("commentType"), commentType)));
}
答案 0 :(得分:2)
您可以告诉持久性提供程序获取与您查询的ProductFeedback.product
个实体的Product
关系,因此ProductFeedback
个对象的简单查询
SELECT pf FROM ProductFeedback pf
会变成
SELECT pf FROM ProductFeedback pf LEFT JOIN FETCH pf.product
使用条件查询,假设您已经有一个Root<ProductFeedback>
对象,您可以通过以下方式急切地获取关联的ProductFeedback.product
对象:
productFeedbackRoot.fetch("product", JoinType.LEFT);
或者如果你有JPA static metamodel classes generated:
productFeedbackRoot.fetch(ProductFeedback_.product, JoinType.LEFT);
答案 1 :(得分:1)
提取策略由hibernate的默认行为决定, 在其文档中解释如 ..
*映射文档中定义的获取策略会影响:
通过get()或load()
进行检索在导航关联时隐式发生的检索
标准查询
如果使用subselect fetching,则HQL查询 无论您使用何种提取策略,都可以保证将定义的非延迟图加载到内存中。 但是,这可能导致多个立即选择用于执行特定的HQL查询。 通常,映射文档不用于自定义提取。相反,我们保留默认行为,并使用HQL中的左连接提取覆盖特定事务。这告诉Hibernate使用外连接在第一个选择中急切地获取关联。在Criteria查询API中,您将使用setFetchMode(FetchMode.JOIN)。 如果要更改get()或load()使用的提取策略,可以使用Criteria查询。例如:
User user = (User) session.createCriteria(User.class)
.setFetchMode("permissions", FetchMode.JOIN)
.add( Restrictions.idEq(userId) )
.uniqueResult();
这是Hibernate相当于一些ORM解决方案所谓的“获取计划”。*
关键是hibernate希望将获取模式设置为事务级别。