@PreUpdate not being called on Seam @Entity
robjellinghaus Jul 6, 2006 2:21 PMOK, so this is probably another Hibernate issue, but still. I'm building my Seam app from the Seam Hibernate example under Tomcat alone (microcontainer, yada yada). I'm trying to declare a @PreUpdate method to protect certain objects from updates (by throwing an exception and killing the session). But my method is never called.
Code:
@Entity @Inheritance(strategy=InheritanceType.JOINED) public class RepObject { ... private Changeset replicatedChangeset; /** * The changeset in which this object was created. Null for head objects; set for all * versioned copies. */ @ManyToOne public Changeset getReplicatedChangeset () { return replicatedChangeset; } ... @PreUpdate private void checkUpdate () { log.debug("Calling checkUpdate on " + this + "..."); if (replicatedChangeset != null) { throw new IllegalStateException("Can't update snapshotted object " + this); } }
The idea is that a RepObject can be copied, and the copy has a non-null "Changeset". The copy then should never ever be updated again. Basically I want it to be "dynamically immutable" (I wish there was a way to flag a particular object as immutable at the Hibernate level, but the best I can do is blow up if you change it and then try to flush).
The test is this. (BlogPostImpl is of course a subclass of RepObject.)
database.enableFilter("priorVersion").setParameter("version", last.getId()); List<BlogPostImpl> priorBlogPosts = database.createQuery("from BlogPostImpl").list(); try { BlogPost prior1 = priorBlogPosts.get(0); prior1.setTitle("changedTitle"); // this should call the @PreUpdate on RepObject, which should blow up here // ... but doesn't! and I can't even see where the @PreUpdate gets read! database.flush(); // assert false; // plan to die if we get this far; should get exception from the flush } catch (Exception e) { // you should never do this, so we don't attempt to support any sort of recovery! log.info("Got expected exception from attempted snapshot update", e); }
But my @PreUpdate method is never called, no exception gets thrown, and I hit the "assert false". And I can see in the log output that the flush *is* causing a single update:
DEBUG 06-07 08:49:12,353 (Log4JLogger.java:debug:84) -Flushed: 0 insertions, 1 updates, 0 deletions to 4 objects ... DEBUG 06-07 08:49:12,393 (Log4JLogger.java:debug:84) -update RepObject set version=?, replicatedChangeset_id=?, replicatedKey=? where id=? and version=? ... DEBUG 06-07 08:49:12,433 (Log4JLogger.java:debug:84) -update BlogPostImpl set content=?, title=? where repobject_id=?
In digging through hibernate-annotations source, I can't see where AnnotationBinder ever looks at the Entity methods to see which of them are flagged with EJB3 callbacks! I would like to trace through the code that sets up the callbacks on this Entity, but I can't find it to trace through!
What am I missing? Can anyone confirm or disconfirm that EJB3 persistence lifecycle annotations actually work with Seam @Entities? I will also post this in the Hibernate EJB3 forum....
Cheers,
Rob