【发布时间】:2015-11-27 12:13:32
【问题描述】:
长期以来,我有以下具有持久性的类使用JPA和Eclipselink作为持久性提供者,它们被成功持久化和查询。
ProductKeyImpl:
@Entity
@Table(name = "PRODUCT_KEY")
@Access(PROPERTY)
public class ProductKeyImpl implements ProductKey {
...
}
派生类 SomeProductKeyImpl:
@Entity
public class SomeProductKeyImpl
extends ProductKeyImpl
implements SomeProductKey {
private String accoStockCode = null;
....
@Column(name = "KEY_3")
public String getAccoStockCode() {
return this.accoStockCode;
}
}
实现接口SomeProductKey:
public interface SomeProductKey extends ProductKey {
String getAccoStockCode();
}
在重构期间,方法 getAccoStockCode() 被移动到由 SomeProductKey 实现的新接口 HasAccoStockCode:
public interface HasAccoStockCode {
String getAccoStockCode();
}
和
public interface SomeProductKey extends ProductKey, HasAccoStockCode {
// getAccoStockCode() removed
}
自此更改以来,查询失败,因为显然 Eclipselink 不仅将 accoStockCode 到 KEY_3 的带注释映射添加到 SQL,而且还添加了来自 HasAccoStockCode 的 getAccoStockCode 方法的默认映射:
Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.6.1.v20150916-55dc7c3): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: java.sql.SQLSyntaxErrorException: ORA-00904: "ACCOSTOCKCODE": ungültiger Bezeichner
Error Code: 904
Call: SELECT ..., ACCOSTOCKCODE, KEY_3 ... FROM PRODUCT_KEY WHERE (ID = ?)
正确的选择语句不应包含 ACCOSTOCKCODE,因为该属性映射到 KEY_3
我在 Eclipselink 2.4.2 上也看到了相同的行为。万一重要,代码在 Java 7 上的 Weblogic 12.1.2 上运行。
除了恢复重构之外我还能做什么?
在@Chris 提问后编辑: 如果我从接口中删除 getAccoStockCode() ,仍然会发生相同的错误(对我来说出乎意料......)。 您的问题将我引向另一个测试用例。 JPQL
SELECT a FROM SomeProductKeyImpl a WHERE a.oid = :id
用 SQL 执行就好了
SELECT ID, PRODUCT_KEY_SUBCLASS_CODE, TIME_STAMP, KEY_3, KEY_4, KEY_2, KEY_1 FROM VRPBOOKING.PRODUCT_KEY WHERE ((ID = ?) AND (PRODUCT_KEY_SUBCLASS_CODE = ?))
bind => [123, SPK]
如果我使用 JPQL 查询超类
SELECT a FROM ProductKeyImpl a WHERE a.oid = :id
生成的SQL是
SELECT ID, PRODUCT_KEY_SUBCLASS_CODE, TIME_STAMP, KEY_1, KEY_2, KEY_3, KEY_4, KEY_5, KEY_6, KEY_7, KEY_8, KEY_9, ACCOSTOCKCODE FROM VRPBOOKING.PRODUCT_KEY WHERE (ID = ?)
bind => [123]
失败了。
【问题讨论】:
-
只是为了澄清,如果从所有接口中删除 getAccoStockCode() 方法,这是否有效?如果您使用 JPQL 中的 accoStockCode 执行查询,会生成什么?
标签: jpa eclipselink