[
http://opensource.atlassian.com/projects/hibernate/browse/HB-92?page=com....
]
Chris Webb commented on HB-92:
------------------------------
Tested against Hibernate Core v3.3.1 GA and original issue still exists. Not sure how to
use PostInsertIdentifierGenerator to resolve. The more recent version of
org.hibernate.id.IdentifierGeneratorFactory in this release allows for a new solution by
modifying the method get(ResultSet rs, Type type) to attempt calling an appropriate
constructor on the 'returned class' to create the identifier object as follows:
public static Serializable get(ResultSet rs, Type type) throws SQLException,
IdentifierGenerationException {
Class clazz = type.getReturnedClass();
if ( clazz == Long.class ) {
return new Long( rs.getLong( 1 ) );
}
else if ( clazz == Integer.class ) {
return new Integer( rs.getInt( 1 ) );
}
else if ( clazz == Short.class ) {
return new Short( rs.getShort( 1 ) );
}
else if ( clazz == String.class ) {
return rs.getString( 1 );
}
else {
// >>>>>> START NEW LOGIC
// Now check to see if the returned class wraps the returned result
// set field. Assumes the returned class defines an appropriate
// public constructor.
// TODO: Rather then assuming an appropriate constructor and using
// reflection maybe the type should define a method that takes a
// result set and returns the appropriate identifier type.
Object identifierValue = null;
try {
try {
Constructor<Serializable> constructor = clazz.getConstructor(new Class[] {
long.class});
identifierValue = new Long(rs.getLong(1));
return constructor.newInstance(new Object[] { identifierValue });
} catch (NoSuchMethodException e) {
try {
Constructor<Serializable> constructor = clazz.getConstructor(new Class[] {
int.class});
identifierValue = new Integer(rs.getInt(1));
return constructor.newInstance(new Object[] { identifierValue });
} catch (NoSuchMethodException e1) {
try {
Constructor<Serializable> constructor = clazz.getConstructor(new Class[] {
short.class});
identifierValue = new Short(rs.getShort(1));
return constructor.newInstance(new Object[] { identifierValue });
} catch (NoSuchMethodException e2) {
try {
Constructor<Serializable> constructor = clazz.getConstructor(new Class[] {
String.class});
identifierValue = rs.getString(1);
return constructor.newInstance(new Object[] { identifierValue });
} catch (NoSuchMethodException e3) {
// Do nothing.
}
}
}
}
} catch (SecurityException e) {
throw new IdentifierGenerationException("Failed to instantiate identifier class
'" + clazz + "' with identifier value '" + identifierValue +
"'", e);
} catch (IllegalArgumentException e) {
throw new IdentifierGenerationException("Failed to instantiate identifier class
'" + clazz + "' with identifier value '" + identifierValue +
"'", e);
} catch (InstantiationException e) {
throw new IdentifierGenerationException("Failed to instantiate identifier class
'" + clazz + "' with identifier value '" + identifierValue +
"'", e);
} catch (IllegalAccessException e) {
throw new IdentifierGenerationException("Failed to instantiate identifier class
'" + clazz + "' with identifier value '" + identifierValue +
"'", e);
} catch (InvocationTargetException e) {
throw new IdentifierGenerationException("Failed to instantiate identifier class
'" + clazz + "' with identifier value '" + identifierValue +
"'", e);
}
// <<<<<< END NEW LOGIC
throw new IdentifierGenerationException( "this id generator generates long,
integer, short or string or classes that wrap those types" );
}
}
Can this issue be reopend and the above change applied?
Retrieving native generated identifiers does not support generic
Hibernate types
--------------------------------------------------------------------------------
Key: HB-92
URL:
http://opensource.atlassian.com/projects/hibernate/browse/HB-92
Project: Hibernate2
Issue Type: Patch
Components: core
Affects Versions: 2.0 final
Reporter: Chris Webb
Assignee: Gavin King
Fix For: 3.0 beta 4
Attachments: patch hb-92.txt
At present Hibernate does not support identifier types other than Short, Integer or Long
for native generated identifiers. This presents a problem when a user defined type is used
to encapsulate an identifier that can support natively generated identifiers. An example
is where a identifier type is defined that stores the natively generated value internally
as a long, thus is similiar to a Long type but not actually a Long type.
The solution is to use the actual identifier type to extract the identifer value from the
appropriate retrieve identifier SQL result set rather than the method
IdentifierGeneratorFactory.get(ResultSet, Class) which in fact has been flagged as
inappropriate in the source code documentation.
A patch has been supplied that does the following:
1. Removes the method get(ResultSet, Class) from IdentifierGeneratorFactory.
2. Changes SequenceGenerator and AbstractEntityPersister to add an 'id' column
alias to the SQL used for retrieving the natively generated identifier.
3 Changes SequenceGenerator, EntityPersister and NormalizedEntityPersister to retrieve
the identifier value from the SQL result set using the identifer type via the method
nullSafeGet(ResultSet rs, String colName, SessionImplementor session, Object owner).
--
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