简体   繁体   中英

Spring/Hibernate: EntityManager multiplies instances

I am trying to return a list of Hibernate entities from a list of ids. The following piece of code is responsible:

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;

  ...
}

When the code has executed I have a list of 3 ids and a list of 60 FooEntity instances!

Under normal circumstances I expect these lines of code to deliver just as many entities as ids. Any ideas what could cause this strange behaviour?

EDIT: Reacting to Thomas' comment below I found out that there are exactly 20 Bar instances for each Foo entity. And every FooEntity is also returned 20-fold.

AFAIK Hibernate by default doesn't remove duplicates from the result lists unless you place a distinct(foo) in the query. Thus you'll get 60 entries in the list for 3 FooEntity instances which are joined with 20 BarEntity instances each, just because the JDBC result set will have 60 rows.

So add a distinct predicate to the query (have a look here: How to get distinct results in hibernate with joins and row-based limiting (paging)? ) or use new LinkedHashSet<FooEntity>( list ) if FooEntity has a meaningful implementation of equals() and hashCode() (I'd not rely on the default implementation since in some situations Hibernate might create multiple instances of the same entity, which results in a "this breaks == semantics" message).

I'm using

criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY);

to remove duplicates from Result

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM