]
Emmanuel Bernard moved EJB-343 to ANN-708:
------------------------------------------
Component/s: (was: EntityManager)
binder
Key: ANN-708 (was: EJB-343)
Project: Hibernate Annotations (was: Hibernate Entity Manager)
id class columns not honored when using orm.xml
-----------------------------------------------
Key: ANN-708
URL:
http://opensource.atlassian.com/projects/hibernate/browse/ANN-708
Project: Hibernate Annotations
Issue Type: Bug
Components: binder
Reporter: Adam Hardy
Attachments: jpabug.zip
Hibernate EntityManager won't map an id-class for an entity. I have ust one entity
with an inner class as the idClass.
Hibernate refuses to load the entity, throwing the following exception (see further
down).
I am using hibernate-annotations-3.3.0ga and hibernate-entitymanager-3.3.1ga.
Mapping:
<?xml version="1.0" encoding="UTF-8"?>
<entity-mappings
xmlns="http://java.sun.com/xml/ns/persistence/orm"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://java.sun.com/xml/ns/persistence/orm
http://java.sun.com/xml/ns/persistence/orm_1_0.xsd"
version="1.0">
<schema>DEV</schema>
<entity class="org.permacode.HabitatSpeciesLink"
access="FIELD">
<table name="HABITAT_SPECIES_LINK" />
<id-class
class="org.permacode.HabitatSpeciesLink$HabitatSpeciesLinkId" />
<attributes>
<id name="habitatId">
<column name="HABITAT_ID" />
</id>
<id name="speciesId">
<column name="SPECIES_ID" />
</id>
</attributes>
</entity>
</entity-mappings>
This is the entity code:
public class HabitatSpeciesLink implements Serializable
{
private static final long serialVersionUID = -7079021236893433038L;
private Long habitatId;
private Long speciesId;
public static class HabitatSpeciesLinkId implements Serializable
{
//private static final long serialVersionUID = 6224703642788723112L;
private Long habitatId;
private Long speciesId;
public Long getHabitatId()
{
return this.habitatId;
}
public void setHabitatId(Long newHabitatId)
{
this.habitatId = newHabitatId;
}
public Long getSpeciesId()
{
return this.speciesId;
}
public void setSpeciesId(Long newSpeciesId)
{
this.speciesId = newSpeciesId;
}
public boolean equals(Object other)
{
if (other == this)
return true;
if (!(other instanceof HabitatSpeciesLinkId))
return false;
HabitatSpeciesLinkId mi = (HabitatSpeciesLinkId) other;
return (habitatId == mi.habitatId || (habitatId != null && habitatId
.equals(mi.habitatId)))
&& (speciesId == mi.speciesId || (speciesId != null &&
speciesId
.equals(mi.speciesId)));
}
public int hashCode()
{
return ((habitatId == null) ? 0
: habitatId.hashCode()) ^ ((speciesId == null) ? 0
: speciesId.hashCode());
}
public String toString()
{
return "habitatId[" + habitatId + "],speciesId[" +
speciesId + "]";
}
}
public Long getHabitatId()
{
return this.habitatId;
}
public void setHabitatId(Long newHabitatId)
{
this.habitatId = newHabitatId;
}
public Long getSpeciesId()
{
return this.speciesId;
}
public void setSpeciesId(Long newSpeciesId)
{
this.speciesId = newSpeciesId;
}
@Override
public int hashCode()
{
final int prime = 31;
int result = 1;
result = prime * result + ((this.getHabitatId() == null) ? 0
: this.getHabitatId().hashCode());
result = prime * result + ((this.getSpeciesId() == null) ? 0
: this.getSpeciesId().hashCode());
return result;
}
@Override
public boolean equals(Object obj)
{
if (this == obj)
return true;
if (obj == null)
return false;
if (!(obj instanceof HabitatSpeciesLink))
return false;
final HabitatSpeciesLink other = (HabitatSpeciesLink) obj;
if (this.getHabitatId() == null)
{
if (other.getHabitatId() != null)
return false;
}
else if (!this.getHabitatId().equals(other.getHabitatId()))
return false;
if (this.getSpeciesId() == null)
{
if (other.getSpeciesId() != null)
return false;
}
else if (!this.getSpeciesId().equals(other.getSpeciesId()))
return false;
return true;
}
}
This is the test code:
EntityManager entityManager = entityManagerFactory.createEntityManager();
HabitatSpeciesLink.HabitatSpeciesLinkId id = new
HabitatSpeciesLink.HabitatSpeciesLinkId();
id.setHabitatId(new Long(123));
id.setSpeciesId(new Long(234));
HabitatSpeciesLink entity = entityManager.find(HabitatSpeciesLink.class, id);
Assert.assertNotNull("should have entity with composite key", entity);
Here's the stacktrace:
javax.persistence.PersistenceException: org.hibernate.exception.SQLGrammarException:
could not load an entity:
[org.permacode.HabitatSpeciesLink#component[habitatId,speciesId]{habitatId=123,
speciesId=234}]
at
org.hibernate.ejb.AbstractEntityManagerImpl.throwPersistenceException(AbstractEntityManagerImpl.java:630)
at
org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:195)
at org.permacode.BugCompositeKeyTest.testCompositeKey(BugCompositeKeyTest.java:181)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at
sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:585)
at org.junit.internal.runners.TestMethod.invoke(TestMethod.java:59)
at org.junit.internal.runners.MethodRoadie.runTestMethod(MethodRoadie.java:98)
at org.junit.internal.runners.MethodRoadie$2.run(MethodRoadie.java:79)
at
org.junit.internal.runners.MethodRoadie.runBeforesThenTestThenAfters(MethodRoadie.java:87)
at org.junit.internal.runners.MethodRoadie.runTest(MethodRoadie.java:77)
at org.junit.internal.runners.MethodRoadie.run(MethodRoadie.java:42)
at
org.junit.internal.runners.JUnit4ClassRunner.invokeTestMethod(JUnit4ClassRunner.java:88)
at org.junit.internal.runners.JUnit4ClassRunner.runMethods(JUnit4ClassRunner.java:51)
at org.junit.internal.runners.JUnit4ClassRunner$1.run(JUnit4ClassRunner.java:44)
at org.junit.internal.runners.ClassRoadie.runUnprotected(ClassRoadie.java:27)
at org.junit.internal.runners.ClassRoadie.runProtected(ClassRoadie.java:37)
at org.junit.internal.runners.JUnit4ClassRunner.run(JUnit4ClassRunner.java:42)
at
org.eclipse.jdt.internal.junit4.runner.JUnit4TestReference.run(JUnit4TestReference.java:38)
at org.eclipse.jdt.internal.junit.runner.TestExecution.run(TestExecution.java:38)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:460)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:673)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:386)
at
org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
Caused by: org.hibernate.exception.SQLGrammarException: could not load an entity:
[org.permacode.HabitatSpeciesLink#component[habitatId,speciesId]{habitatId=123,
speciesId=234}]
at org.hibernate.exception.SQLStateConverter.convert(SQLStateConverter.java:67)
at org.hibernate.exception.JDBCExceptionHelper.convert(JDBCExceptionHelper.java:43)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1865)
at
org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:48)
at
org.hibernate.loader.entity.AbstractEntityLoader.load(AbstractEntityLoader.java:42)
at
org.hibernate.persister.entity.AbstractEntityPersister.load(AbstractEntityPersister.java:2992)
at
org.hibernate.event.def.DefaultLoadEventListener.loadFromDatasource(DefaultLoadEventListener.java:395)
at
org.hibernate.event.def.DefaultLoadEventListener.doLoad(DefaultLoadEventListener.java:375)
at
org.hibernate.event.def.DefaultLoadEventListener.load(DefaultLoadEventListener.java:139)
at
org.hibernate.event.def.DefaultLoadEventListener.proxyOrLoad(DefaultLoadEventListener.java:195)
at
org.hibernate.event.def.DefaultLoadEventListener.onLoad(DefaultLoadEventListener.java:103)
at org.hibernate.impl.SessionImpl.fireLoad(SessionImpl.java:878)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:815)
at org.hibernate.impl.SessionImpl.get(SessionImpl.java:808)
at
org.hibernate.ejb.AbstractEntityManagerImpl.find(AbstractEntityManagerImpl.java:175)
... 23 more
Caused by: java.sql.SQLException: Column 'HABITATSPE0_.HABITATID' is either not
in any table in the FROM list or appears within a join specification and is outside the
scope of the join specification or appears in a HAVING clause and is not in the GROUP BY
list. If this is a CREATE or ALTER TABLE statement then 'HABITATSPE0_.HABITATID'
is not a column in the target table.
at org.apache.derby.impl.jdbc.SQLExceptionFactory.getSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.Util.generateCsSQLException(Unknown Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.wrapInSQLException(Unknown
Source)
at org.apache.derby.impl.jdbc.TransactionResourceImpl.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.ConnectionChild.handleException(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement.<init>(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement20.<init>(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedPreparedStatement30.<init>(Unknown Source)
at org.apache.derby.jdbc.Driver30.newEmbedPreparedStatement(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
at org.apache.derby.impl.jdbc.EmbedConnection.prepareStatement(Unknown Source)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:497)
at org.hibernate.jdbc.AbstractBatcher.getPreparedStatement(AbstractBatcher.java:415)
at org.hibernate.jdbc.AbstractBatcher.prepareQueryStatement(AbstractBatcher.java:139)
at org.hibernate.loader.Loader.prepareQueryStatement(Loader.java:1538)
at org.hibernate.loader.Loader.doQuery(Loader.java:661)
at
org.hibernate.loader.Loader.doQueryAndInitializeNonLazyCollections(Loader.java:224)
at org.hibernate.loader.Loader.loadEntity(Loader.java:1851)
... 35 more
Caused by: ERROR 42X04: Column 'HABITATSPE0_.HABITATID' is either not in any
table in the FROM list or appears within a join specification and is outside the scope of
the join specification or appears in a HAVING clause and is not in the GROUP BY list. If
this is a CREATE or ALTER TABLE statement then 'HABITATSPE0_.HABITATID' is not a
column in the target table.
at org.apache.derby.iapi.error.StandardException.newException(Unknown Source)
at org.apache.derby.impl.sql.compile.ColumnReference.bindExpression(Unknown Source)
at org.apache.derby.impl.sql.compile.ResultColumn.bindExpression(Unknown Source)
at org.apache.derby.impl.sql.compile.ResultColumnList.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.SelectNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.DMLStatementNode.bindExpressions(Unknown Source)
at org.apache.derby.impl.sql.compile.DMLStatementNode.bind(Unknown Source)
at org.apache.derby.impl.sql.compile.CursorNode.bindStatement(Unknown Source)
at org.apache.derby.impl.sql.GenericStatement.prepMinion(Unknown Source)
at org.apache.derby.impl.sql.GenericStatement.prepare(Unknown Source)
at
org.apache.derby.impl.sql.conn.GenericLanguageConnectionContext.prepareInternalStatement(Unknown
Source)
... 48 more
I'm using Derby, Hypersonic, H2 or postgresql. It seems to be database-independent.
This is the generated SQL:
select habitatspe0_.habitatId as habitatId0_0_, habitatspe0_.speciesId as speciesId0_0_
from DEV.HABITAT_SPECIES_LINK habitatspe0_ where habitatspe0_.habitatId=? and
habitatspe0_.speciesId=?
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators: