簡體   English   中英

Spring / Hibernate:EntityManager乘實例

[英]Spring/Hibernate: EntityManager multiplies instances

我正在嘗試從ID列表返回Hibernate實體的列表。 以下代碼段負責:

String sql = "select id from foo where some condition is met";
List<Long> ids = jdbcTemplate.queryForList(sql, Long.class); // 3 ids ..
List<FooEntity> list =  ((Session) this.entityManager.getDelegate())
        .createCriteria(FooEntity.class)
        .add(Restrictions.in("id", ids)).list(); // .. -> 60 entities

...

@Entity
public class FooEntity implements Serializable {

  @Id
  @GeneratedValue(strategy = GenerationType.IDENTITY)
  @Column(name = "id")
  private long id;

  @OneToMany(
    targetEntity = BarEntity.class,
    cascade = { CascadeType.ALL },
    fetch = FetchType.EAGER)
  @JoinTable(
    name = "foo_bar",
    joinColumns = @JoinColumn(name = "foo_id"),
    inverseJoinColumns = @JoinColumn(name = "bar_id"))
  private List<BarEntity> bars;

  ...
}

代碼執行完后,我將列出3個id60個FooEntity實例!

在正常情況下,我希望這些代碼行可以提供與id一樣多的實體。 有什么想法會導致這種奇怪的行為嗎?

編輯:對下面Thomas的評論做出反應,我發現每個Foo實體正好有20個Bar實例。 並且每個FooEntity也會返回20倍。

默認情況下,除非您在查詢中放置一個distinct(foo) ,否則AFAIK Hibernate不會從結果列表中刪除重復項。 因此,您將在3個FooEntity實例的列表中獲得60個條目, FooEntity實例都與20個BarEntity實例結合BarEntity ,因為JDBC結果集將有60行。

因此,在查詢中添加一個distinct謂詞(請看這里: 如何在具有連接和基於行的限制(分頁)的休眠狀態下獲取不同的結果? )或如果FooEntity具有有意義的實現,則使用new LinkedHashSet<FooEntity>( list )equals()hashCode() (我不依賴默認實現,因為在某些情況下,Hibernate可能會創建同一實體的多個實例,這會導致出現“此中斷==語義”消息)。

我正在使用

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

從結果中刪除重復項

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM