0

I´m using wicket and hibernate. I got two objects category and group. A group can have several categorys and a category can have several groups.

My Problem (its pretty hard for me to explain it in english): It seems that in my list I get from the database are equal objects as the size of the categorys I store to the group (while in the database is only ONE group).

Example:

Categorys 1, 2, 3, 4

Group test

test got the category 1 and 2. So in my panel the group test shows twice. If I would add the category 3 the group test would been showed three times.

this is how I get data of my database:

public List<T> getAll( Class theClass) {
    List<T> entity = null;
    Transaction trns = null;
    Session session = sessionFactory.openSession();
    try {         
        trns = session.beginTransaction();
        entity = session.createCriteria(theClass).list();
        session.getTransaction().commit();
    } catch (RuntimeException e) {
        e.printStackTrace();
    }finally {
    session.flush();
    session.close();
 }
    return entity;
 }

inside my panel I get a list of my groups like this:

List<Group> groupList = new ArrayList<Group>();
groupList = groupDao.getAll(Group.class);

if I debug through my panel and hold on at this page in groupList is the SAME object equal to the size of categorys stored to the group. Inside the database is still only ONE row. picture of the debugged variable <code>groupList</code>

Group entity:

@Entity
@Table(name = "GROUP_USER")
public class Group implements Serializable{

@Id
@GeneratedValue
@Column(name = "GROUP_ID")
private int groupID;

@ManyToMany(cascade = {CascadeType.MERGE}, fetch = FetchType.EAGER)
@JoinTable(name="GROUP_TO_CATEGORY",
            joinColumns={@JoinColumn(name="GROUP_ID")}, 
            inverseJoinColumns={@JoinColumn(name="CATEGORY_ID")})
private Set<Category> categorys = new HashSet<Category>();
//constructor.. getter and setter..
}

Category entity:

@Entity
@Table(name = "CATEGORY")
public class Category implements Serializable{

@Id
@GeneratedValue
@Column(name = "CATEGORY_ID")
private int categoryId;

@ManyToMany(mappedBy="categorys", fetch = FetchType.EAGER)
private Set<Group> groups = new HashSet<Group>();
//constructor.. getter and setter..
}
monti
  • 455
  • 7
  • 25

1 Answers1

2

This is caused by your use of eager fetching, which is usually a bad idea anyway.

You should try to change your mapping to do lazy fetching of collections if at all possible. That will solve this issue and any new issues it introduces can be better handled by other means such as "Open Session in View". You can see some discussion of that in this question.

If you have a fetch that really must be done eagerly, however, you can correct this issue by using a ResultTransformer that consolidates the duplicates as follows:

public List<T> getAll( Class theClass) {
    List<T> entity = null;
    Transaction trns = null;
    Session session = sessionFactory.openSession();
    try {         
        trns = session.beginTransaction();
        Criteria criteria = session.createCriteria(theClass);
        criteria.setResultTransformer(Criteria.DISTINCT_ROOT_ENTITY)
        entity = criteria.list();
        session.getTransaction().commit();
    } catch (RuntimeException e) {
        e.printStackTrace();
    }finally {
    session.flush();
    session.close();
 }
    return entity;
 }
Community
  • 1
  • 1
Don Roby
  • 40,677
  • 6
  • 91
  • 113