I just ran into a problem with id generation, here's my case:
Hibernate version:
3
Mapping documents:
Code:
<class name="Persistent" table="A" mutable="false">
<id name="id" column="gemeente_id" access="field" unsaved-value="0">
<generator class="identity"/>
</id>
</class>
Full stack trace of any exception that occurs:Code:
Thread [main] (Suspended (breakpoint at line 95 in UnsavedValueFactory))
UnsavedValueFactory.getUnsavedIdentifierValue(String, Getter, Type, Constructor) line: 95
PropertyFactory.buildIdentifierProperty(PersistentClass, IdentifierGenerator) line: 67
EntityMetamodel.<init>(PersistentClass, SessionFactoryImplementor) line: 147
SingleTableEntityPersister(AbstractEntityPersister).<init>(PersistentClass, EntityRegionAccessStrategy, SessionFactoryImplementor) line: 457
SingleTableEntityPersister.<init>(PersistentClass, EntityRegionAccessStrategy, SessionFactoryImplementor, Mapping) line: 131
PersisterFactory.createClassPersister(PersistentClass, EntityRegionAccessStrategy, SessionFactoryImplementor, Mapping) line: 84
SessionFactoryImpl.<init>(Configuration, Mapping, Settings, EventListeners, SessionFactoryObserver) line: 261
Configuration.buildSessionFactory() line: 1327
Name and version of the database you are using:Apache Derby 10.4.2
Code:
public interface Identifiable <ID extends java.io.Serializable> {
public ID getId ();
}
public class PersistenClass implements Identifiable <Long> {
public Long getId () {...}
}
Now this causes the init of SessionFactoryImpl to crash. Apparently there's a call in TypeFactory.heuristicType (String, Properties) which returns a Type for Serializable. As SerializableType is not a subclass of IdentifierType this subsequently gives a ClassCastException in UnsavedValueFactory.getUnsavedIdentifierValue(String, Getter identifierGetter, Type identifierType, Constructor constructor).
Now this is understandable as the return type of the getId () method is still Serializable. But what surprises me is that although I set access to field the return type of the property accessor has been taken. If I make sure the accessor method and the attribute have different names I don't run into this problem. This is because by default ReflectHelper.getter (Class, String) tries a property accessor first and if that fails a direct accessor, it doesn't take the access value into account.
Quote:
access (optional - defaults to property): The strategy Hibernate should use for accessing the property value.
Am I using Hibernate in a wrong way or is this a bug?