[英]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個id和60個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.