queries with "in" referencing entities can have some null ids even if they are not #267

Closed
anthony-o opened this Issue Nov 5, 2012 · 6 comments

Comments

Projects
None yet
2 participants
@anthony-o
Contributor

anthony-o commented Nov 5, 2012

Hibernate sometimes proxy some entities which results in certain cases entityManager.getEntityManagerFactory().getPersistenceUnitUtil().getIdentifier(entity) to return null even if there is an id set !

In my case, I'm in JPQLSerializer line 429 (ids.add(util.getIdentifier(entity))) and util.getIdentifier(entity) returns null whereas my entity has an id of 498 (entity.getClass().getMethod("getIdDelegation").invoke(entity) = 498) !

The class of that entity is currently "Delegation_$$_javassist_2" which is an Hibernate proxy.

See http://stackoverflow.com/questions/3787716/introspection-table-name-of-an-object-managed-by-hibernate-javassistlazyiniti

Here is the patch that is necessary. Instead of

            for (Object entity : (Collection<?>)rhs.getConstant()) {
                ids.add(util.getIdentifier(entity));
            }

one should write

            for (Object entity : (Collection<?>)rhs.getConstant()) {
                if (entity instanceof HibernateProxy) {
                    entity = ((HibernateProxy)entity).getHibernateLazyInitializer().getImplementation();
                }
                ids.add(util.getIdentifier(entity));
            }
@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Nov 5, 2012

Member

This is a Hibernate specific solution. Also it's a filed bug in the Hibernate JIRA
https://hibernate.onjira.com/browse/HHH-7561

Do you have a suggestion how to solve this using the methods of EntityManager and PersistenceUnitUtil?

Member

timowest commented Nov 5, 2012

This is a Hibernate specific solution. Also it's a filed bug in the Hibernate JIRA
https://hibernate.onjira.com/browse/HHH-7561

Do you have a suggestion how to solve this using the methods of EntityManager and PersistenceUnitUtil?

@anthony-o

This comment has been minimized.

Show comment
Hide comment
@anthony-o

anthony-o Nov 6, 2012

Contributor

MMmh, perhaps you could attach a "EntityIdentifierResolver" to the JPQLSerializer which would do a PersistenceUnitUtil.getIdentifier by default and if the EM is Hibernate, then when creating the JPQLSerializer, it would attach a "HibernateEntityIdentifierResolver" instead which would check for the HibernateProxy...

Like that the "hibernate specific" would be deported to that other EntityIdentifierResolver class.

Contributor

anthony-o commented Nov 6, 2012

MMmh, perhaps you could attach a "EntityIdentifierResolver" to the JPQLSerializer which would do a PersistenceUnitUtil.getIdentifier by default and if the EM is Hibernate, then when creating the JPQLSerializer, it would attach a "HibernateEntityIdentifierResolver" instead which would check for the HibernateProxy...

Like that the "hibernate specific" would be deported to that other EntityIdentifierResolver class.

@anthony-o

This comment has been minimized.

Show comment
Hide comment
@anthony-o

anthony-o Nov 6, 2012

Contributor

Moreover, if I'm correct, there's no obligation to convert the list of entity to a list of ids, I think in JPA it's correct to write "where entity in (:collection)" and then jpaQuery.setParameter("collection", Collection), it's the EntityManager which would then resolve it and create the correct SQL query with the ID.

Contributor

anthony-o commented Nov 6, 2012

Moreover, if I'm correct, there's no obligation to convert the list of entity to a list of ids, I think in JPA it's correct to write "where entity in (:collection)" and then jpaQuery.setParameter("collection", Collection), it's the EntityManager which would then resolve it and create the correct SQL query with the ID.

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Nov 6, 2012

Member

EclipseLink fails without this transformation. I will enable this transformation only for EclipseLink.

Member

timowest commented Nov 6, 2012

EclipseLink fails without this transformation. I will enable this transformation only for EclipseLink.

@anthony-o

This comment has been minimized.

Show comment
Hide comment
@anthony-o

anthony-o Nov 6, 2012

Contributor

Good ! I just hope I'm correct concerning Hibernate & the collection parameter :)
I tried to google about that feature but found nothing at the moment... it's just I think I've already done that in a project and it was working.

Contributor

anthony-o commented Nov 6, 2012

Good ! I just hope I'm correct concerning Hibernate & the collection parameter :)
I tried to google about that feature but found nothing at the moment... it's just I think I've already done that in a project and it was working.

@timowest

This comment has been minimized.

Show comment
Hide comment
@timowest

timowest Nov 19, 2012

Member

Released in 2.9.0

Member

timowest commented Nov 19, 2012

Released in 2.9.0

@timowest timowest closed this Nov 19, 2012

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment