如何避免JPA一对多映射(同一模型中的两个一对多关系)中的冗余数据(列表提取)?

时间:2019-03-14 06:09:54

标签: java spring-boot spring-mvc jpa spring-data-jpa

我有三个模特。 BookingDetail与LookupFoodItem和LookupFacility模型都有一对多的关系。在我的数据库中,有4个LookupFacility记录和4个LookupFoodItem记录。当我获取一个BookingDetail记录时,应该有4个LookupFoodItem记录,但是我发现有16个记录是多余的。如何解决这个问题,以便只获取真实记录而不是冗余数据?

public class BookingDetail {
      @OneToMany(mappedBy = "bookingDetail", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      public List<LookupFacility> lookupFacilities;
      @OneToMany(mappedBy = "bookingDetail", cascade = CascadeType.ALL, fetch = FetchType.EAGER)
      public List<LookupFoodItem> lookupFoodItems;
}

public class LookupFacility {
      @ManyToOne
      @JoinColumn(name="booking_details_id")
      BookingDetail bookingDetail;
}

public class LookupFoodItem{
      @ManyToOne
      @JoinColumn(name="booking_details_id")
      BookingDetail bookingDetail;
}

当我使用JPA从数据库中获取BookingDetail信息时,它给了我类似的冗余数据

LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}
LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}
LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}
LookupFoodItem{id=40, name='Beef ', price=120.0}
LookupFoodItem{id=41, name='Polao', price=300.0}
LookupFoodItem{id=42, name='Crab Fry', price=299.0}
LookupFoodItem{id=43, name='Chicken Soup', price=100.0}

LookupFoodItem和LookupFacilities之间没有关系。

2 个答案:

答案 0 :(得分:1)

不知道您使用的是LOMBOK还是实际缺少的getter和setter,所以我在这里添加了它。

使用Set而不是List并将抓取更改为Lazy。这是我的工作解决方案之一。希望这会有所帮助。

随时根据需要更改注释。有关更多详细信息,this包含一些信息

library(ggplot2)
source("https://gist.githubusercontent.com/benmarwick/2a1bb0133ff568cbe28d/raw/fb53bd97121f7f9ce947837ef1a4c65a73bffb3f/geom_flat_violin.R")

plot3 <- ggplot(data = my_data2, aes(y = Proportion, x = Leads, fill = Leads)) +
  geom_flat_violin(position = position_nudge(x = .2, y = 0), alpha = .8) +
  geom_point(aes(y = Proportion, color = Leads), 
             position = position_jitter(width = .15), size = .5, alpha = 0.8) +
  geom_boxplot(width = .1, guides = FALSE, outlier.shape = NA, alpha = 0.5) +
  facet_wrap(~Hypothesis, nrow = 2) +
  expand_limits(x = 5.25) +
  guides(fill = FALSE) +
  guides(color = FALSE) +
  scale_color_brewer(palette = "Spectral") +
  scale_fill_brewer(palette = "Spectral") +
  coord_flip() +
  theme_bw() 

plot3

对于课程public class BookingDetail { private Set<LookupFacility> lookupFacilities = new HashSet<LookupFacility>(); private Set<LookupFoodItem> lookupFoodItems = new HashSet<LookupFoodItem>(); @OneToMany(fetch = FetchType.LAZY, mappedBy = "bookingDetail", cascade = CascadeType.ALL, orphanRemoval = true) @Fetch(FetchMode.SUBSELECT) public Set<LookupFacility> getLookupFacilities() { return lookupFacilities; } public void setLookupFacilities(final Set<LookupFacility> lookupFacilities) { this.lookupFacilities = lookupFacilities; } @OneToMany(fetch = FetchType.LAZY, mappedBy = "bookingDetail", cascade = CascadeType.ALL, orphanRemoval = true) @Fetch(FetchMode.SUBSELECT) public Set<LookupFoodItem> getLookupFoodItems() { return lookupFoodItems; } public void setLookupFoodItems(final Set<LookupFoodItem> lookupFoodItems) { this.lookupFoodItems = lookupFoodItems; } } LookupFacility,我们

LookupFoodItem

答案 1 :(得分:0)

如果您打算在不加载所有其他关系的情况下不获取记录,我全都建议您将fetchType.LAZY添加到您的关系映射中,并包括此json ignore @JsonIgnore,以解决运行时数据加载初始化错误。

请参见下面的示例

@JsonIgnore
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "booking_details_id")
private BookingDetail  bookingDetail;

使用这种方法,您应该会很好。希望有帮助。