PersistentMap incorrectly flags rows for insertion when data contains NULLs
---------------------------------------------------------------------------
Key: HHH-2351
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HHH-2351
Project: Hibernate3
Type: Bug
Components: core
Versions: 3.0.5, 3.2.1
Environment: Found in 3.0.5, but the code in 3.2.1 contains the same error.
Reporter: Matt Doran
Attachments: partial-map-null-fix.patch
There is a bug in the org.hibernate.collection.PersistentMap implementation that can cause
hibernate to try to insert duplicate rows when the map values from the database contain
null.
The issue is caused when incorrectly testing if an row exists in a Map. The persistent
map testing whether map values are == null instead of checking to see if the key exists.
i.e. using Map.get(key) == null instead of Map.containsKey(key).
This is incorrect, because the map values are allowed to contain null.
This problem can bee seen in the following code:
public boolean needsInserting(Object entry, int i, Type elemType)
throws HibernateException {
final Map sn = (Map) getSnapshot();
Map.Entry e = (Map.Entry) entry;
return e.getValue()!=null && sn.get( e.getKey() )==null;
}
If the map contains an entry: key1 -> NULL , and we try to update the value , then the
above code will incorrectly result in a new row being attempted to be inserted (instead of
updated).
Instead of checking whether the values == null the Map.containKey() method should be
used.
I think similar bugs also exist in the "needsUpdating" and
"getDeletes" methods. I've attached a possible patch for the
"needsInserting" and "needsUpdating" methods, but I don't
understand everything that's going on here or the code in "getDeletes" ....
but I'm sure you guys will know the right answer!
SIDE NOTE:
The reason this has just started causing us an issue in our product (PaperCut NG), is that
we are porting to Oracle, which turns empty strings into NULLs (which is annoying). For
other databases we stored blank strings in the values, but in Oracle they become NULLs
(whether we like it or not). We then start getting errors about violating uniqueness
constraints when Hibernate incorrectly these attempts to re-insert the rows in the
database.
This is of critical importance to us. In the short-term, our work-around might involve
just deleting rows that contain NULL.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
http://opensource.atlassian.com/projects/hibernate/secure/Administrators....
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira