-->
These old forums are deprecated now and set to read-only. We are waiting for you on our new forums!
More modern, Discourse-based and with GitHub/Google/Twitter authentication built-in.

All times are UTC - 5 hours [ DST ]



Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 
Author Message
 Post subject: help with Interceptor
PostPosted: Tue Feb 21, 2006 11:08 am 
Newbie

Joined: Tue Feb 21, 2006 10:31 am
Posts: 7
hello all,
I'm trying to implement an Interceptor in order to historize inserts/updates on my DB.

I'm still using Hibernate 2 and by the moment cannot move to H3.

I read lots of docs and before trying the triggers/views solution found in http://blog.hibernate.org/cgi-bin/blosx ... ggers.html I'm trying to implement my own Interceptor based on the sample in http://hibernate.bluemars.net/Documenta ... nterceptor.

in order to do that I have:

public interface Historizable extends Serializable{
public Set getHistoryEntries();
public void setHistoryEntries(Set set);
}

I have my persister that implements Historizable

I have another persister that's the HistoryElement

I have my HistoryInterceptor where I implemeted all the methods I need.

My first problem is on inserts: my onSave is:

public boolean onSave(Object obj, Serializable id, Object[] newValues, String[] properties, Type[] types) throws CallbackException {
if (!(obj instanceof Historizable)) {
return false;
}
Historizable h = (Historizable) obj;
if (log.isDebugEnabled()) {
log.debug("Inserting " + obj + " with id " + id + " new=" + Arrays.asList(newValues) + " props=" + Arrays.asList(properties));
}
System.out.println("sono Historizable");
// Ensure that the set is not null
Set entries = h.getStoricoEntries();
if (entries == null) {
entries = new HashSet();
h.setHistoryEntries(entries);
}
HistoryEntry entry = new HistoryEntry();
entry.setUser(getUser());
entry.setDate(new Timestamp(new Date().getTime()));
entry.setOperation("created");

entries.add(entry);
return false;
}

when I debug the code I find out that before the invocation of the save() method I have my HistoryEntries set empty and that's right: when the control passes correctly to my onSave() method in my Interceptor it correctly creates the HistoryEntry and puts it in my Historizable object but when the control passes right before the flush() method I find that the history set is again empty so it's like if the history set has not been "persistered".

My other problem is when I try to update: I receive the net.sf.hibernate.TransientObjectException: object references an unsaved transient instance... and I found out the answer that talks about the creation of another Session with the same connection of the "master" session but, truely, I didn't understand it well.

my onFlushDirty() method is

public boolean onFlushDirty(Object obj, Serializable id, Object[] newValues, Object[] oldValues, String[] properties, Type[] types)
throws CallbackException {
System.out.println("onFlushDirty");
if (log.isEnabledFor(Priority.INFO)) {
log.info("Updating " + obj + " with id " + id + " new=" + Arrays.asList(newValues) + " old=" + Arrays.asList(oldValues) + " props="
+ Arrays.asList(properties));
}

if (!(obj instanceof Historizable)) {
return false;
}
Historizable h = (Historizable) obj;

// Won't work:
// net.sf.hibernate.TransientObjectException: object references an unsaved
// transient instance - save the transient instance before flushing:
// de.micromata.hibernate.HistoryEntry
// Set entries = h.getHistoryEntries();
//
// get the copy from the map
Set entries = (Set) histories.get(obj);
for (int i = 0; i < properties.length; i++) {
// Skip the historyEntries
if (properties[i].equals("historyEntries") == true) {
continue;
}
Object oldOne = oldValues[i];
Object newOne = newValues[i];
// Check for changes
if (oldOne == null && newOne == null) {
continue;
}
if (newOne instanceof PersistentCollection) {
// Collections must be compared against the snapshot
PersistentCollection collection = (PersistentCollection) newValues[i];
if (collection.isDirectlyAccessible() == false) {
continue;
}
// retrieve Snapshot
oldOne = collection.getCollectionSnapshot().getSnapshot();
if (oldOne instanceof Map && newOne instanceof Set) {
// a Set is internally stored as Map
oldOne = ((Map) oldOne).values();
}
}
if (oldOne != null && oldOne.equals(newOne) == true) {
continue;
}
// Generate a new entry

HistoryEntry entry = new HistoryEntry();
entry.setUser(getUser());
entry.setDate(new Timestamp(new Date().getTime()));
entry.setOperation("update");
entry.setProperties(properties[i]);
entry.setOldValue(format(oldOne));
entry.setNewValue(format(newOne));
if (log.isDebugEnabled()) {
log.debug("Changed " + properties[i] + " from " + oldOne + " to " + newOne);
}
// and store it.
entries.add(entry);
}
// h.setHistoryEntries(entries);

return false;
}

How can I solve these problems? I already used Hibernate for a project that didn't need historicization so it's my first time trying to historize all the "updates/inserts" in my DB.

thx in advance for any help


Top
 Profile  
 
Display posts from previous:  Sort by  
Forum locked This topic is locked, you cannot edit posts or make further replies.  [ 1 post ] 

All times are UTC - 5 hours [ DST ]


You cannot post new topics in this forum
You cannot reply to topics in this forum
You cannot edit your posts in this forum
You cannot delete your posts in this forum

Search for:
© Copyright 2014, Red Hat Inc. All rights reserved. JBoss and Hibernate are registered trademarks and servicemarks of Red Hat, Inc.