I have an entity (Person) with a derived property that maps to another entity (Alias) using a specific formula.
This other entity has a composite key.
Here are classes with annotations I used to reproduce the problem I have in my application:
Code:
@Entity(name = "testAlias")
public class Alias {
private AliasId aliasId;
private Person person;
@EmbeddedId
public AliasId getAliasId() {
return aliasId;
}
public void setAliasId(AliasId aliasId) {
this.aliasId = aliasId;
}
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "personId", nullable = false)
public Person getPerson() {
return person;
}
public void setPerson(Person person) {
this.person = person;
}
}
Code:
@Embeddable
public class AliasId implements Serializable {
private String firstId;
private String secondId;
@Column(name = "firstId")
public String getFirstId() {
return firstId;
}
public void setFirstId(String firstId) {
this.firstId = firstId;
}
@Column(name = "secondId")
public String getSecondId() {
return secondId;
}
public void setSecondId(String secondId) {
this.secondId = secondId;
}
}
Code:
@Entity(name = "testPerson")
public class Person {
private String id;
private Alias bestCurrentAlias;
@Id
@Column(name = "personId")
public String getId() {
return id;
}
public void setId(String id) {
this.id = id;
}
@OneToOne(fetch = FetchType.LAZY)
@JoinColumnsOrFormulas({
@JoinColumnOrFormula(formula =
@JoinFormula(value = "(select a.firstId from testAlias a where a.personId = personId)", referencedColumnName = "firstId")),
@JoinColumnOrFormula(formula =
@JoinFormula(value = "(select a.secondId from testAlias a where a.personId = personId)", referencedColumnName = "secondId"))
})
public Alias getBestCurrentAlias() {
return bestCurrentAlias;
}
public void setBestCurrentAlias(Alias bestCurrentAlias) {
this.bestCurrentAlias = bestCurrentAlias;
}
}
When I get a Person object everything seems to map correctly.
The following works:
Code:
Person p = (Person)session.get(Person.class, "1");
assertNotNull(p.getBestCurrentAlias());
The following also works:
Code:
Person p = (Person) session.createQuery("from testPerson p where p.bestCurrentAlias.person.id = ?")
.setParameter(0, "1")
.uniqueResult();
assertNotNull(p.getBestCurrentAlias());
The problem I am having is that I get an exception when I try to use bestCurrentAlias in a HQL query:
Code:
Person p = (Person)session.createQuery("from testPerson p where p.bestCurrentAlias.id.firstId = ?")
.setParameter(0, "first")
.uniqueResult();
// Exception is thrown
Here is the exception:
Quote:
java.lang.NullPointerException
at org.hibernate.persister.entity.AbstractPropertyMapping.toColumns(AbstractPropertyMapping.java:103)
at org.hibernate.persister.entity.BasicEntityPropertyMapping.toColumns(BasicEntityPropertyMapping.java:62)
at org.hibernate.persister.entity.AbstractEntityPersister.toColumns(AbstractEntityPersister.java:1443)
at org.hibernate.hql.ast.tree.FromElementType.toColumns(FromElementType.java:354)
at org.hibernate.hql.ast.tree.FromElementType.toColumns(FromElementType.java:323)
at org.hibernate.hql.ast.tree.FromElement.toColumns(FromElement.java:491)
at org.hibernate.hql.ast.tree.DotNode.getColumns(DotNode.java:133)
at org.hibernate.hql.ast.tree.DotNode.initText(DotNode.java:252)
at org.hibernate.hql.ast.tree.DotNode.resolve(DotNode.java:246)
at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:117)
at org.hibernate.hql.ast.tree.FromReferenceNode.resolve(FromReferenceNode.java:113)
at org.hibernate.hql.ast.HqlSqlWalker.resolve(HqlSqlWalker.java:866)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.expr(HqlSqlBaseWalker.java:1321)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.exprOrSubquery(HqlSqlBaseWalker.java:4383)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.comparisonExpr(HqlSqlBaseWalker.java:3856)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.logicalExpr(HqlSqlBaseWalker.java:1907)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.whereClause(HqlSqlBaseWalker.java:822)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.query(HqlSqlBaseWalker.java:608)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.selectStatement(HqlSqlBaseWalker.java:292)
at org.hibernate.hql.antlr.HqlSqlBaseWalker.statement(HqlSqlBaseWalker.java:235)
at org.hibernate.hql.ast.QueryTranslatorImpl.analyze(QueryTranslatorImpl.java:254)
at org.hibernate.hql.ast.QueryTranslatorImpl.doCompile(QueryTranslatorImpl.java:185)
at org.hibernate.hql.ast.QueryTranslatorImpl.compile(QueryTranslatorImpl.java:136)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:101)
at org.hibernate.engine.query.HQLQueryPlan.<init>(HQLQueryPlan.java:80)
at org.hibernate.engine.query.QueryPlanCache.getHQLQueryPlan(QueryPlanCache.java:98)
at org.hibernate.impl.AbstractSessionImpl.getHQLQueryPlan(AbstractSessionImpl.java:156)
at org.hibernate.impl.AbstractSessionImpl.createQuery(AbstractSessionImpl.java:135)
at org.hibernate.impl.SessionImpl.createQuery(SessionImpl.java:1760)
....
The toColumns(String alias, String propertyName) method in AbstractPropertyMapping throws the NullPointerException when the propertyName passed is "bestCurrentAlias.person.id".
I am using 3.5.1-Final (but I get the same behavior with 3.5.5-Final).
I have tested this against Oracle10g and HSQLDB.
Any one have an idea what my problem might be?