I have the following classes:
Code:
@Entity
public class SimpleEntity {
@Id
private int id;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "entityA")
private EntityConnection connection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "entityB")
private List<EntityConnection> otherConnections;
// accessors
}
Code:
@Entity
@IdClass(EntityConnectionPK.class)
public class EntityConnection {
@Id
@JoinColumn(name = "entity_a_id")
@OneToOne
private SimpleEntity entityA;
@Id
@JoinColumn(name = "entity_b_id")
@ManyToOne
private SimpleEntity entityB;
// accessors
}
Code:
public class EntityConnectionPK implements Serializable {
private int entityA;
private int entityB;
// accessors, equals, hashcode
}
Executing the following query:
Code:
TypedQuery<SimpleEntity> q = em.createQuery("select e from SimpleEntity e where e.id = 1", SimpleEntity.class);
SimpleEntity foundEntity = q.getResultList().get(0);
results in:
Code:
Exception in thread "main" java.lang.NullPointerException
at org.hibernate.persister.entity.AbstractEntityPersister.loadByUniqueKey(AbstractEntityPersister.java:2200)
at org.hibernate.type.EntityType.loadByUniqueKey(EntityType.java:661)
at org.hibernate.type.EntityType.resolve(EntityType.java:441)
at org.hibernate.engine.internal.TwoPhaseLoad.initializeEntity(TwoPhaseLoad.java:150)
at org.hibernate.loader.Loader.initializeEntitiesAndCollections(Loader.java:1012)
at org.hibernate.loader.Loader.doQuery(Loader.java:889)
at org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:289)
at org.hibernate.loader.Loader.doList(Loader.java:2449)
at org.hibernate.loader.Loader.doList(Loader.java:2435)
at org.hibernate.loader.Loader.listIgnoreQueryCache(Loader.java:2276)
at org.hibernate.loader.Loader.list(Loader.java:2271)
at org.hibernate.loader.hql.QueryLoader.list(QueryLoader.java:470)
at org.hibernate.hql.internal.ast.QueryTranslatorImpl.list(QueryTranslatorImpl.java:355)
at org.hibernate.engine.query.spi.HQLQueryPlan.performList(HQLQueryPlan.java:196)
at org.hibernate.internal.SessionImpl.list(SessionImpl.java:1105)
at org.hibernate.internal.QueryImpl.list(QueryImpl.java:100)
at org.hibernate.ejb.QueryImpl.getResultList(QueryImpl.java:252)
After some debugging I found that Hibernate ignores the mappedBy values and uses names with prepended "_identifierMapper". After changing the annotations to:
Code:
@Entity
public class SimpleEntity {
@Id
private int id;
@OneToOne(cascade = CascadeType.ALL, mappedBy = "_identifierMapper.entityA")
private EntityConnection connection;
@OneToMany(cascade = CascadeType.ALL, mappedBy = "_identifierMapper.entityB")
private List<EntityConnection> otherConnections;
// accessors
}
the code works, but I don't want to do framework hacking. Is there something I'm missing about mappings with IdClass or is it a bug? It works this way in 3.6.6.Final, 4.0.0Beta2 and 4.0.0Beta4.