How to fetch a oneToMany lazy relationship using hibernate and jpa
问题:hibernate状态忽略了我在查询中输入的JOIN FETCH。我的意图是从已设置为惰性的oneToMany关系中检索product_item元素,但这没有发生。
这是我要运行的查询:
1 2 3 4 5 6 7 8 9 | em.createQuery("SELECT DISTINCT e" + "FROM ereturn e," + "user shipper" + "JOIN FETCH product_item pi on pi.ereturn.id = e.id" + "JOIN FETCH product_definition pd on pi.product.id = pd.id" + "WHERE" + "shipper.id = e.shipper.id" + "AND e.scanDateTime IS NOT NULL" + "AND e.status = 'RECEIVED'").getResultList() |
这是查询执行计划:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | Hibernate: select distinct ereturn0_.id as id1_1_, ereturn0_.barcode as barcode2_1_, ereturn0_.carrier as carrier27_1_, ereturn0_.consignee as consign28_1_, ereturn0_.consigneeFirstName as consigne3_1_, ereturn0_.consigneeLastName as consigne4_1_, ereturn0_.creationtime as creation5_1_, ereturn0_.disabled as disabled6_1_, ereturn0_.dispatchedDate as dispatch7_1_, ereturn0_.failedReturnPOBoxPrivateBag as failedRe8_1_, ereturn0_.globalCondition as globalCo9_1_, ereturn0_.globalId as globalI10_1_, ereturn0_.groupName as groupNa11_1_, ereturn0_.invoice as invoice12_1_, ereturn0_.notes as notes13_1_, ereturn0_.pickupDateTime as pickupD14_1_, ereturn0_.pickupDateTimeOffset as pickupD15_1_, ereturn0_.pieces as pieces16_1_, ereturn0_.processedByShipper as process17_1_, ereturn0_.reasonToReturn as reasonT18_1_, ereturn0_.returnAction as returnA19_1_, ereturn0_.returnMethod as returnM20_1_, ereturn0_.returned as returne21_1_, ereturn0_.rma as rma22_1_, ereturn0_.scanDateTime as scanDat23_1_, ereturn0_.shipper as shipper29_1_, ereturn0_.status as status24_1_, ereturn0_.trackingNumber as trackin25_1_, ereturn0_.weight as weight26_1_ from ereturn ereturn0_ cross join user user1_ inner join product_item productite2_ on ( productite2_.ereturn=ereturn0_.id ) inner join product_definition productdef3_ on ( productite2_.product=productdef3_.id ) where user1_.id=ereturn0_.shipper and ( ereturn0_.scanDateTime is not null ) and ereturn0_.status='RECEIVED' |
执行查询,但未获取ereturn.productItems,因此会抱怨json序列化。
这些是我的课程:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 | public class Ereturn { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name ="shipper") private User shipper = new User("", UserType.SHIPPER); @ManyToOne @JoinColumn(name ="consignee") private User consignee; @ManyToOne @JoinColumn(name ="carrier") private User carrier = new User("", UserType.CARRIER); @JsonManagedReference(value="ereturn-parcel") @OneToMany(mappedBy ="ereturn", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) private List<Parcel> parcels = new ArrayList<>(); @JsonManagedReference(value="ereturn-productItems") @OneToMany(mappedBy ="ereturn", fetch = FetchType.LAZY, cascade = CascadeType.ALL, orphanRemoval = true) private List<ProductItem> productItems = new ArrayList<>(); ... } public class ProductItem { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name ="product") private ProductDefinition product; @JsonBackReference(value="ereturn-productItems") @ManyToOne @JoinColumn(name ="ereturn") private Ereturn ereturn; ... } public class ProductDefinition { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @ManyToOne @JoinColumn(name ="shipper") private User shipper; @JsonIgnore @OneToMany(mappedBy ="product", cascade = CascadeType.REFRESH) private List<ProductItem> productItems = new ArrayList<>(); ... } public class User implements SecurityContext { @Id @GeneratedValue(strategy = GenerationType.IDENTITY) private Long id; @JsonIgnore @OneToMany(mappedBy ="shipper", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Set<ProductDefinition> productDefinitions = new HashSet<>(); @JsonIgnore @OneToMany(mappedBy ="shipper", fetch = FetchType.LAZY, cascade = CascadeType.ALL) private Set<Ereturn> ereturns = new HashSet<>(); // Client process ereturn to finish it @JsonIgnore @OneToMany(mappedBy ="shipper", cascade = CascadeType.ALL) private Set<Contract> contracts = new HashSet<>(); private Boolean disabled = Boolean.FALSE; ... } |
问题1:为什么查询未从product_item表中获取元素?
问题2:上面的查询返回的元素数量与数据库返回的行数相同,而不是通过返回进行分组。为什么会这样?
我相信具有
要使
1 2 | SELECT e FROM eReturn e JOIN FETCH e.productItens |
请记住不要使用获取的别名来应用