[hibernate-issues] [Hibernate-JIRA] Commented: (HHH-7167) The new natural id code introduced in 4.1.1 depends on the order the entity persisters are loaded which leads to fatal errors

Guillaume Smet (JIRA) noreply at atlassian.com
Tue Mar 13 19:37:50 EDT 2012


    [ https://hibernate.onjira.com/browse/HHH-7167?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=45940#comment-45940 ] 

Guillaume Smet commented on HHH-7167:
-------------------------------------

Hi again,

I've spent some time this evening trying to write a test case so that you can reproduce it but I don't think I can get it without inserting all our entities in the test case.

The fact is that the order used to instantiate the entityPersisters is based on Configuration.classes which is a HashMap (and not a Linked one). So you don't have any guarantee that the order will be respected even if the classes have been inserted in the right order by MetadataSourceQueue.processAnnotatedClassesQueue (which calls Configuration.MappingsImpl.addClass() and addClass() inserts the PersistentClass in Configuration.classes).

As far as I can see from my attempts to produce a test case, you won't be able to reproduce the problem with only a few entities because the HashMap keeps the right order. In our application, with more than 100 entities, the order of the HashMap isn't the order of insertion at all thus the problem.

That said, I'm pretty sure the problem can also be triggered by mixing .hbm files and annotations so changing Configuration.classes from an HashMap to a LinkedHashMap probably won't be sufficient. We don't do it but as I saw test cases here and there (especially in JPA modelgen) supporting it, I suppose it's a supported configuration.

>From what I can see:
- either you change Configuration.classes to something sorted and reproduce the magic of MetadataSourceQueue.orderAndFillHierarchy on the final Configuration.classes obtained with all the entities (annotations + hbm files)
- or you don't count on the fact that entityPersisters are loaded in the right order and generate the natural id sql query of the root persister before using it in AbstractEntityPersister.generateEntityIdByNaturalIdSql()

Hope this helps.

-- 
Guillaume

> The new natural id code introduced in 4.1.1 depends on the order the entity persisters are loaded which leads to fatal errors
> -----------------------------------------------------------------------------------------------------------------------------
>
>                 Key: HHH-7167
>                 URL: https://hibernate.onjira.com/browse/HHH-7167
>             Project: Hibernate ORM
>          Issue Type: Bug
>          Components: core
>    Affects Versions: 4.1.1
>            Reporter: Guillaume Smet
>            Priority: Critical
>
> Hi,
> After upgrade to 4.1.1, our application doesn't work anymore because the sqlEntityIdByNaturalIdString field of the entity persister is null while it shouldn't be.
> The problem is that the new code requires the entityPersisters to be postInstantiate()d in a specific order namely the root entity persister should be initialized before the child classes (which is not guaranteed at all and is not the case in our application because of the way our classes are organized).
> In our case, the entities are loaded in this order (pseudo code):
> {code}
> @Entity
> ConcreteClass extends AbstractClass {
> }
> @Entity
> AbstractClass {
> @Id, @NaturalId
> }
> {code}
> Which is a problem because of the way AbstractEntityPersister.generateEntityIdByNaturalIdSql() now works:
> {code}
> private String generateEntityIdByNaturalIdSql() {
> 		EntityPersister rootPersister = getFactory().getEntityPersister( getRootEntityName() );
> 		if ( rootPersister != this ) {
> 			if ( rootPersister instanceof AbstractEntityPersister ) {
> 				return ( (AbstractEntityPersister) rootPersister ).sqlEntityIdByNaturalIdString;
> 			}
> 		}
> {code}
> -> if the root persister is not postInstantiate()d yet (which is our case here), sqlEntityIdByNaturalIdString is null and so is the one of the concrete class leading to fatal error when trying to execute queries using the natural id.
> In this case, we should force the postInstantiation of the root entity persister before using sqlEntityIdByNaturalIdString (or we should at least generate its sqlEntityIdByNaturalIdString).
> Feel free to ping me if you need any further information.
> -- 
> Guillaume

--
This message is automatically generated by JIRA.
For more information on JIRA, see: http://www.atlassian.com/software/jira

        


More information about the hibernate-issues mailing list