ここでばかげたことをしているだけだと思っています...
の JPA アノテーションを設定しようとしMap<String, Phone>
ており、次のスタック トレースを取得しています。
Exception [EclipseLink-6069] (Eclipse Persistence Services - 2.4.1.v20121003-ad44345): org.eclipse.persistence.exceptions.QueryException
Exception Description: The field [EMPLOYEE.PHONE_TYPE] in this expression has an invalid table in this context.
Query: ReadAllQuery(name="phones" referenceClass=Phone )
at org.eclipse.persistence.exceptions.QueryException.invalidTableForFieldInExpression(QueryException.java:739)
at org.eclipse.persistence.internal.expressions.FieldExpression.validateNode(FieldExpression.java:281)
at org.eclipse.persistence.expressions.Expression.normalize(Expression.java:3259)
at org.eclipse.persistence.internal.expressions.DataExpression.normalize(DataExpression.java:369)
at org.eclipse.persistence.internal.expressions.FieldExpression.normalize(FieldExpression.java:208)
at org.eclipse.persistence.internal.expressions.SQLSelectStatement.normalize(SQLSelectStatement.java:1377)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.buildNormalSelectStatement(ExpressionQueryMechanism.java:546)
at org.eclipse.persistence.internal.queries.ExpressionQueryMechanism.prepareSelectAllRows(ExpressionQueryMechanism.java:1700)
at org.eclipse.persistence.queries.ReadAllQuery.prepareSelectAllRows(ReadAllQuery.java:721)
at org.eclipse.persistence.queries.ReadAllQuery.prepare(ReadAllQuery.java:657)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:614)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.checkPrepare(ObjectLevelReadQuery.java:883)
at org.eclipse.persistence.queries.DatabaseQuery.checkPrepare(DatabaseQuery.java:575)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:820)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1109)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:393)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1197)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584)
at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:112)
at org.eclipse.persistence.internal.indirection.QueryBasedValueHolder.instantiate(QueryBasedValueHolder.java:99)
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:88)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiateImpl(UnitOfWorkValueHolder.java:161)
at org.eclipse.persistence.internal.indirection.UnitOfWorkValueHolder.instantiate(UnitOfWorkValueHolder.java:222)
at org.eclipse.persistence.internal.indirection.DatabaseValueHolder.getValue(DatabaseValueHolder.java:88)
at org.eclipse.persistence.indirection.IndirectMap.buildDelegate(IndirectMap.java:110)
at org.eclipse.persistence.indirection.IndirectMap.getDelegate(IndirectMap.java:330)
at org.eclipse.persistence.indirection.IndirectMap.size(IndirectMap.java:637)
at org.eclipse.persistence.internal.queries.MapContainerPolicy.sizeFor(MapContainerPolicy.java:830)
at org.eclipse.persistence.internal.indirection.TransparentIndirectionPolicy.instantiateObject(TransparentIndirectionPolicy.java:386)
at org.eclipse.persistence.mappings.ForeignReferenceMapping.buildCloneFromRow(ForeignReferenceMapping.java:285)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildAttributesIntoWorkingCopyClone(ObjectBuilder.java:1594)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildWorkingCopyCloneFromRow(ObjectBuilder.java:1741)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObjectInUnitOfWork(ObjectBuilder.java:668)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:605)
at org.eclipse.persistence.internal.descriptors.ObjectBuilder.buildObject(ObjectBuilder.java:564)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.buildObject(ObjectLevelReadQuery.java:777)
at org.eclipse.persistence.queries.ReadAllQuery.registerResultInUnitOfWork(ReadAllQuery.java:783)
at org.eclipse.persistence.queries.ReadAllQuery.executeObjectLevelReadQuery(ReadAllQuery.java:434)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeDatabaseQuery(ObjectLevelReadQuery.java:1150)
at org.eclipse.persistence.queries.DatabaseQuery.execute(DatabaseQuery.java:852)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.execute(ObjectLevelReadQuery.java:1109)
at org.eclipse.persistence.queries.ReadAllQuery.execute(ReadAllQuery.java:393)
at org.eclipse.persistence.queries.ObjectLevelReadQuery.executeInUnitOfWork(ObjectLevelReadQuery.java:1197)
at org.eclipse.persistence.internal.sessions.UnitOfWorkImpl.internalExecuteQuery(UnitOfWorkImpl.java:2875)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1602)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1584)
at org.eclipse.persistence.internal.sessions.AbstractSession.executeQuery(AbstractSession.java:1549)
at org.eclipse.persistence.internal.jpa.QueryImpl.executeReadQuery(QueryImpl.java:231)
at org.eclipse.persistence.internal.jpa.QueryImpl.getResultList(QueryImpl.java:411)
at aaa.Test.main(Test.java:20)
作成されたテーブルは次のようになります。
EMP_PHONE
=================================
EMP_ID PHONES_ID PHONE_TYPE
------ --------- ----------
42 1 NULL
EMPLOYEE
=================================
ID
--
42
PHONE
=================================
ID NUM
-- --------
1 867-5309
何かファンキーなことが起こっていることを教えてくれるようです.EclipselinkNULL
PHONE_TYPE
が探している方法は、 ->EMPLOYEE.PHONE_TYPE
からの関係について考えていると思います。PHONE
EMPLOYEE
JPA エンティティは次のように定義されます。電話マップは単方向であり、電話オブジェクトは複数の従業員で共有する必要があります (私の実際のタイプではありませんが、この単純化された例は問題を示しています)
@Entity
public class Employee {
@Id private long id;
@OneToMany(cascade=CascadeType.ALL)
@JoinTable(name="EMP_PHONE", joinColumns=@JoinColumn(name="EMP_ID"))
@MapKeyColumn(name="PHONE_TYPE")
private Map<String, Phone> phones = new HashMap<String, Phone>();
public Employee() {}
public Employee(long id) {
this.id = id;
}
public long getId() {
return id;
}
public Map<String, Phone> getPhones() {
return phones;
}
}
@Entity
public class Phone {
@Id
private long id;
private String num;
public String getNum() {
return num;
}
public Phone() {}
public Phone(String num) {
this.num = num;
}
public Phone(long id, String num) {
this.id = id;
this.num = num;
}
public long getId() {
return id;
}
}
次のテストコードを使用して
EntityManagerFactory factory = Persistence.createEntityManagerFactory("test");
EntityManager em = factory.createEntityManager();
Employee employee = new Employee(42);
// exception will occur with or without phones added to the map
employee.getPhones().put("home", new Phone(1, "867-5309"));
em.getTransaction().begin();
em.persist(employee);
em.getTransaction().commit();
Query q = em.createQuery("select o from Employee o");
q.setHint("javax.persistence.cache.storeMode", "REFRESH");
q.getResultList(); // EXCEPTION THROWN HERE
およびpersistence.xml:
<?xml version='1.0' encoding='UTF-8' ?>
<persistence xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance'
xsi:schemaLocation='http://java.sun.com/xml/ns/persistence
http://java.sun.com/xml/ns/persistence/persistence_2_0.xsd'
version='2.0' xmlns='http://java.sun.com/xml/ns/persistence'>
<persistence-unit name='test' transaction-type='RESOURCE_LOCAL'>
<provider>org.eclipse.persistence.jpa.PersistenceProvider</provider>
<class>aaa.Phone</class>
<class>aaa.Employee</class>
<shared-cache-mode>NONE</shared-cache-mode>
<properties>
<property name='javax.persistence.jdbc.user' value='uuuuuuuu' />
<property name='javax.persistence.jdbc.password' value='pppppppp' />
<property name='javax.persistence.jdbc.driver'
value='oracle.jdbc.driver.OracleDriver' />
<property name='javax.persistence.jdbc.url'
value='jdbc:oracle:thin:@localhost:1521:xe' />
<property name='eclipselink.ddl-generation'
value='drop-and-create-tables' />
<property name='eclipselink.ddl-generation.output-mode' value='database' />
</properties>
</persistence-unit>
</persistence>
Oracle XE 11g をデータベースとして使用して、Windows 7 で実行しています。洞察を事前にありがとう!