@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