【发布时间】:2016-08-08 11:17:46
【问题描述】:
我在 MySQL 中有两个实体,如下所示。 nnm_tran 的主键是 id 和 source 的组合。讨价还价的主键其实是nnm_tran表的外键链接
我正在尝试使用 JPA 继承来表示这些。
nnm_tran 实体
@Entity
@Table(name = "nnm_tran")
@IdClass(CommonTransactionKey.class)
@Inheritance(strategy = InheritanceType.JOINED)
@DiscriminatorColumn(name = "bargain_flag", discriminatorType = DiscriminatorType.CHAR)
@DiscriminatorValue("N")
public class CommonTransaction {
@Id
@Column(name = "id", nullable = false)
private String transactionId;
@Column(name = "plan_number", nullable = false)
private String planNumber;
@Column(name = "tran_date")
private LocalDateTime transactionDatetime;
@Column(name = "bargain_flag")
private String bargainFlag;
...
}
讨价还价实体
@Data
@EqualsAndHashCode(callSuper = true)
@Entity
@Table(name = "bargains")
@DiscriminatorValue("B")
@PrimaryKeyJoinColumns({ @PrimaryKeyJoinColumn(name = "nnm_tran_id", referencedColumnName = "id"), @PrimaryKeyJoinColumn(name = "nnm_tran_source", referencedColumnName = "source") })
public class Bargain extends CommonTransaction implements Serializable {
@Column(name = "unit_price")
private BigDecimal unitPrice;
@Column(name = "client_price")
private BigDecimal clientPrice;
...
}
我认为到目前为止这一切都正确连接。当我附加一个带有自定义查询的 spring-data 存储库时,我的问题就出现了。
存储库
public interface CommonTransactionRepository extends CrudRepository<CommonTransaction, CommonTransactionKey> {
@Query("select t from CommonTransaction t left join IoPlan p ON t.planNumber = p.planNumber "
+ "where (p.planNumber is NULL or p.planNumber = '') "
+ "and t.transactionDatetime between ?1 and ?2 "
+ "and t.cancelled = false")
public Iterable<CommonTransaction> findOrphanedTransactionsByTranDate(LocalDateTime fromDate, LocalDateTime toDate);
...
}
当它被代理并执行该方法时,它会生成 SQL 语句SELECT DISTINCT nnm_tran.bargain_flag FROM nnm_tran t1 LEFT OUTER JOIN io_plan t0 ON (t1.plan_number = t0.plan_number) WHERE ((((t0.plan_number IS NULL) OR (t0.plan_number = ?)) AND (t1.tran_date BETWEEN ? AND ?)) AND (t1.CANCELLED = ?))
问题在于 nnm_tran 表别名为 t1 但鉴别器列引用了完整的表名 nnm_tran.bargain_flag 结果很可爱
UnitOfWork(17171249)--Exception [EclipseLink-4002] (Eclipse Persistence Services - 2.5.2.v20140319-9ad6abd): org.eclipse.persistence.exceptions.DatabaseException
Internal Exception: com.mysql.jdbc.exceptions.jdbc4.MySQLSyntaxErrorException: Unknown column 'nnm_tran.bargain_flag' in 'field list'
这里的问题是,我做错了什么还是这是 spring-data 和/或 eclipselink 中的错误?
版本:spring-data 1.7.2、Eclipselink 2.5.2、MySQL 5.6.28
【问题讨论】:
-
我怀疑发布的JPA会导致发布的SQL查询(JPA查询以
SELECT t FROM CommonTransaction t开头,而SQL查询是SELECT DISTINCT nnm_tran.bargain_flag FROM nnm_tran t1。您发布实际代码吗?我也无法使用您提供的版本重现您所指出的行为。您可以运行 my sample app 中包含的测试以查看生成的正确 SQL。您可以复制示例并将其调整到您的代码中,以查看您为什么不正确SQL。 -
首先,感谢您花时间为此设置测试。它有助于我看到树林中的木头。 :-) 要回答您的问题,是的,这是实际代码,是的,SQL 是 JPA 查询的结果。我已经设法弄清楚了这个怪癖,虽然不是特别优雅,但它现在对我有用。我已经在我的回答中详细说明了。
-
EclipseLink 可以使用“选择不同的 discriminatorColumn”查询来获取它需要构建的子类,然后为每个类发出单独的查询。这是可配置的,如下所述:wiki.eclipse.org/EclipseLink/UserGuide/JPA/… 尝试使用定制器将其设置为使用外连接来读取单个查询中的子类,如果查询中有排序或分页,则应使用它。
-
@Chris Holy s**t 零食。这让我自己的解决方案大吃一惊。添加了定制器并关闭并运行。它确实只需要切换到外部连接。 :-) 谢谢
标签: java mysql jpa eclipselink spring-data