gpt4 book ai didi

java - EclipseLink JPA "invalid table in this context"与@OneToMany map

转载 作者:塔克拉玛干 更新时间:2023-11-03 04:13:51 25 4
gpt4 key购买 nike

我希望我只是在这里做了一些愚蠢的事情......

我正在尝试为 Map<String, Phone> 设置 JPA 注释并获取以下堆栈跟踪。

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

NULL PHONE_TYPE似乎告诉我一些奇怪的事情正在发生,以及 eclipselink 正在寻找 EMPLOYEE.PHONE_TYPE 的方式让我觉得它在考虑来自 PHONE 的关系-> EMPLOYEE而不是相反。

JPA 实体定义如下。 phones 映射是单向的,Phone 对象应该由多个 Employees 共享(不是我的实际类型,但这个简化的例子演示了这个问题)

@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>

我在 Windows 7 上运行,使用 Oracle XE 11g 作为数据库。提前感谢您的任何见解!

最佳答案

这看起来像 EclipseLink 错误 364922 :

An entity with uni-directional OneToMany property and @MapKeyColumn annotation has the correct database tables created, with the mapping table containing a "key column, but persisting an entity only populates the id columns and not the key column. The persist operation does not throw an error, but subsequent queries soon fail with the following error: Exception Description: The field [ORGANIZATION.MAILINGADDRESSES_KEY] in this expression has an invalid table in this context.

就其值(value)而言,我使用 Hibernate/H2 测试了您的代码,它运行良好。

更新

我刚刚使用 EclipseLink 对此进行了测试。如果您为 MapKeyColumn 显式设置表,则键会被正确填充。即:

@MapKeyColumn(name="PHONE_TYPE", table="EMP_PHONE")

关于java - EclipseLink JPA "invalid table in this context"与@OneToMany map ,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16247479/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com