[hibernate-issues] [Hibernate-JIRA] Commented: (HB-92) Retrieving native generated identifiers does not support generic Hibernate types

Chris Webb (JIRA) noreply at atlassian.com
Wed Nov 26 20:27:16 EST 2008


    [ http://opensource.atlassian.com/projects/hibernate/browse/HB-92?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=31831#action_31831 ] 

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.jspa
-
For more information on JIRA, see: http://www.atlassian.com/software/jira

        



More information about the hibernate-issues mailing list