0

I got problem with my application. I want to use @PreUpdate & @PrePersist to calculate some fields before updating, or creating entry. This methods lokks like this:

@PreUpdate
public void recount(){
    if (applications != null){
        this.appAssigned = getAssignmentCount();
        this.appWaiting = getOutstandingCount();
    }
}

@PrePersist
public void count(){
    if (applications != null){
        this.appAssigned = getAssignmentCount();
        this.appWaiting = getOutstandingCount();
    }
}

Whole app compiles without any errors or warnings, but when I update an entry, those methods are not invoked. I tried to debug problem, and only think I can tell is that those methods, are never invoked. No information in logs, nothing.

Anyone got any idea?

EDIT:

This entity has some basic fields, and few collection fetched lazy. This method has one job - before updating entity I need to recalculate some thing depending on those lazily fetched collections. Of course, I fetch those collections, change something, set changed collection, and then want to merge. @Pre methods are not invoked, but entity merges without any problems, all collections are changed, no errors.

FUN FACT!! I tired manually to recalculate before merging, so I added line:

myEntity.setAppAssigned(myEntity.getAssignmentCount());
entityMenager.merge(myEntity);

AND THEN @Pre methods were fired O.O I tried messing with hashcode, and equal methods, I tried merging and persisting entity, nothing works, except of manually setting one field, then methods are fired. Can anyone understands this??

EDIT 2

here is method I use to change collections:

public void doStuff(Long id, Long appId){       
 Entity entity = entityMenager.findAndFetchCollections(id);

        Set<Foo> appList = entity .getApplications();

        Foo foo = new foo();
//here I find Foo I want to change, and remove it from collection
        Iterator<Foo> iterator = appList.iterator();
        while (iterator.hasNext()){
            foo = iterator.next();
            if (foo.getId().equals(appId)){
                iterator.remove();
                break;
            }
        }

//do some stuff with found foo and add it back to collection, then set collection back to entity
        foo.setFooDate(new Date());
        foo.setFooStatus("PENDING");
        foo.setFooIndex(fooCount + 1);
        appList.add(foo);
        entity.setFoo(appList);

        entityMenager.merge(entity);

}

in this case methods are not invoked. If I add before merging li:

entity.setFooWaiting(entity.getFooCount());

then methods are invoked. I tried also with EntityListener but it works same way as methods in Entity class.

Lukas Novicky
  • 921
  • 1
  • 19
  • 44
  • I'm confused. I just want to make sure... This methods are located in entity class, right? Not in JSF Managed bean? Can you provide more complete source? – skegg99 May 19 '14 at 12:29
  • @skegg99, yes apparently. We just want to know if there's thrown exception when trying to insert/update the entity instance. – Omar May 19 '14 at 12:36
  • This methods are in my entity class. No exception at all. Nothing. Entity is updated correctly, but without changes that should be made by this methods. – Lukas Novicky May 19 '14 at 13:37
  • It seems that the entity really isn't updated or persisted in the flow where you expect it to be. Perhaps only the related entities are updated/persisted. Could you debug and post the generated SQL? – Magnilex May 20 '14 at 08:51
  • Entity itself is not changed - only collections of other entities are changed, and I want to recalculate their status and update two fields in main entity. But they if they are fetched, and changed, aren't they supposed to indicate that the entity also has changed? – Lukas Novicky May 20 '14 at 09:03

1 Answers1

1

I think that I know what's going on - suggestion from @Magnilex helped me to get it:
it looks that @PreUpdate and @PrePersist don't look at entity as a entity but as a SQL mapping - even though I update collections in my entity class, I don't update any field in SQL table, and that's why those methods are not invoked. When I manually set one basic field, that is present not only in my entity mapping, but is also a column in SQL table, only then hibernate counts it as a 'change' and use those methods.

Does it make sense?

Lukas Novicky
  • 921
  • 1
  • 19
  • 44
  • 1
    I think it actually looks at the entities. But, if the entity itself doesn't need to be updated, the methods won't be called. The generated SQL is just a way to debug what the ORM framework really does beneath the hood. In this case, to determine whether it is updating the entity or not. – Magnilex May 20 '14 at 09:39
  • But entity is changed - I take collection of other entities attached to this entity, perform action - changing few fields, sometimes adding elements and set changed collection back to entity. So if hibernate looks at entity, it is changed. – Lukas Novicky May 20 '14 at 10:08
  • I'm not really sure, but I guess the key is that you change other entities. Hibernate sees no need to update your entity, hence the method is not called. I guess this behaviour can depend on how the relations are mapped. I am not really sure though, just speculating. – Magnilex May 20 '14 at 10:19
  • I also find this article : [link]http://stackoverflow.com/questions/1786343/preupdate-not-firing-when-adding-to-a-collection?rq=1[link] and it looks like I was right - no need to change table, so hibernate doesn't fires methods:/ nasty behavior:/ – Lukas Novicky May 20 '14 at 10:20
  • Well, you got your answer there my friend. – Magnilex May 20 '14 at 10:21
  • Seams like it. Thank you for your help-your pointers was helpful with finding source of my problem. – Lukas Novicky May 20 '14 at 10:24