2

I use Spring JPA.

I have two entity Timesheet and User. They have many-to-one relationship. I defined them as

@Entity
@Table(name = "timesheet")
public class TimeSheet implements java.io.Serializable {
... 
private User user;
......

    @ManyToOne(fetch = FetchType.LAZY)
        @JoinColumn(name = "user_id", referencedColumnName = "user_id", nullable = false)
        public User getUser() {
            return user;
        }

        public void setUser(User user) {
            this.user = user;
        }

and

@Entity
@Table(name = "user")
public class User implements java.io.Serializable {

...

private List<TimeSheet> timesheet = ShrinkableLazyList
    .decorate(new ArrayList(), FactoryUtils
            .instantiateFactory(TimeSheet.class));
...


    @OneToMany(fetch = FetchType.LAZY, mappedBy = "user")
    public List<TimeSheet> getTimesheet() {
        return timesheet;
    }

    public void setTimesheet(List<TimeSheet> timesheet) {
        this.timesheet = timesheet;
    }

I usually used entityManager.merge(timeSheet) to save new timesheet/update existing timesheet. The problem is when I tried to update an existing timesheet, it will generate extrema large number of select query to get all(maybe not) timesheet records before doing update action. I As more and more timesheets have been submitted, the merge function become slower.

When I updated a user, I have the same problem.

I changed it to session.merge, the same problem.

I changed it to session.saveOrUpdate. It is fast, but sometimes will throw session exception.

I still prefer to use merge method, but dont know what cause the slowness problem?

Please help. Thanks.

Update 1:

the extreme number of query I got like this, and it takes about 2 minutes

........................................
Hibernate: select timesheet0_.timesheet_id as ........... 
Hibernate: select timesheet0_.timesheet_id as ........... 
Hibernate: select timesheet0_.timesheet_id as ........... 
Hibernate: select timesheet0_.timesheet_id as ........... 
Hibernate: select timesheet0_.timesheet_id as .........
     .........................................

Update 2:

@Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
public TimeSheet saveTimeSheet(TimeSheet timeSheet) {
//  Session s=entityManager.unwrap(HibernateEntityManager.class).getSession();
//  s.saveOrUpdate(timeSheet);
    TimeSheet result = entityManager.merge(timeSheet);
//      TimeSheet result=timeSheet;
        return result;

}
Alex
  • 617
  • 2
  • 9
  • 21
  • http://stackoverflow.com/questions/161224/what-are-the-differences-between-the-different-saving-methods-in-hibernate – NimChimpsky Feb 24 '12 at 15:33
  • Which query (queries) is (are) executed? It should only load the time sheet that you asked to merge. – JB Nizet Feb 24 '12 at 15:34
  • Please format the SQL with `hibernate.format_sql=true` and post it as update to your question. This is unreadable here. What *session exception* is thrown? – tscho Feb 24 '12 at 16:01
  • You might want to take a look at [this article](http://blog.xebia.com/2009/03/23/jpa-implementation-patterns-saving-detached-entities/). – tscho Feb 24 '12 at 16:15
  • Please post the complete SQL select query (one instance) that is executed on update. Is `Timesheet` annotated with `@Entity(selectBeforeUpdate=true)`? – tscho Feb 24 '12 at 16:27
  • Hi, did you find the problem with your mappings? We are facing a similar issue now. Thanks! – Rafael Sisto Oct 29 '13 at 12:48

0 Answers0