【发布时间】:2017-01-10 16:34:51
【问题描述】:
我正在将遗留应用程序转换为 Spring Boot、Groovy、JPA 解决方案,并发现自己遇到了以下形式的查询:
SELECT ...
FROM table1, table2
WHERE table1.field1 = table2.field1 AND
table1.field2 = table2.field2 and
table2.field3 = 'ABC'
如您所见,连接是在三个字段上执行的,其中两个基于 table1 中的数据,第三个字段是常量字符串。
因此,对于我搜索的内容(即 http://docs.oracle.com/cd/E13189_01/kodo/docs40/full/html/ref_guide_mapping_notes_nonstdjoins.html ),我发现解决方案是:
@Entity
@Table(name = "Table1")
class Table1 {
// other column definitions here
@OneToOne(cascade = CascadeType.ALL)
@JoinColumns([
@JoinColumn(name="field1", referencedColumnName="field1"),
@JoinColumn(name="field2", referencedColumnName="field2"),
@JoinColumn(name="table2.field3", referencedColumnName="'ABC'")]
)
Table2 table2
}
当我运行此程序时,我收到“无法找到具有逻辑名称的列:table2 中的‘ABC’”异常:
Caused by: org.hibernate.MappingException: Unable to find column with logical name: 'ABC' in table2
at org.hibernate.cfg.Ejb3JoinColumn.checkReferencedColumnsType(Ejb3JoinColumn.java:854) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.cfg.BinderHelper.createSyntheticPropertyReference(BinderHelper.java:241) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.cfg.ToOneFkSecondPass.doSecondPass(ToOneFkSecondPass.java:100) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processEndOfQueue(InFlightMetadataCollectorImpl.java:1786) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processFkSecondPassesInOrder(InFlightMetadataCollectorImpl.java:1730) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.boot.internal.InFlightMetadataCollectorImpl.processSecondPasses(InFlightMetadataCollectorImpl.java:1617) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:278) ~[hibernate-core-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.metadata(EntityManagerFactoryBuilderImpl.java:847) ~[hibernate-entitymanager-5.0.9.Final.jar:5.0.9.Final]
at org.hibernate.jpa.boot.internal.EntityManagerFactoryBuilderImpl.build(EntityManagerFactoryBuilderImpl.java:874) ~[hibernate-entitymanager-5.0.9.Final.jar:5.0.9.Final]
at org.springframework.orm.jpa.vendor.SpringHibernateJpaPersistenceProvider.createContainerEntityManagerFactory(SpringHibernateJpaPersistenceProvider.java:60) ~[spring-orm-4.3.2.RELEASE.jar:4.3.2.RELEASE]
但是,正如所引用的示例所指出的,此解决方案似乎仅适用于 @OneToMany 关系。
我正在尝试连接到完全不可能更改架构的旧 Informix 数据库。 除此之外,我的 build.gradle 看起来像这样(反正相关部分):
buildscript {
repositories {
// ...
}
dependencies { classpath('org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE') }
}
apply plugin: 'groovy'
apply plugin: 'spring-boot'
defaultTasks 'clean', 'assemble'
sourceCompatibility = 1.8
targetCompatibility = 1.8
repositories {
// ...
}
dependencies {
compile "org.springframework.boot:spring-boot-starter-web"
compile "org.springframework.boot:spring-boot-starter-actuator"
compile "org.springframework.boot:spring-boot-starter-data-jpa"
compile "org.springframework:spring-jms"
compile "org.apache.cxf:cxf-rt-frontend-jaxws:${cxfVersion}"
compile "org.apache.cxf:cxf-rt-transports-http:${cxfVersion}"
compile "org.codehaus.groovy:groovy-all:2.4.4"
compile "informix:informix-jdbc:${informixVersion}"
compile "informix:informix-jdbcx:${informixVersion}"
testCompile "org.springframework.boot:spring-boot-starter-test"
testCompile "org.spockframework:spock-core:${spockVersion}"
testCompile "org.spockframework:spock-spring:${spockVersion}"
testCompile "junit:junit:4.12"
testCompile "org.springframework:spring-test"
}
有人遇到过这样的问题吗?或者解决这种情况的正确方法是什么?
非常感谢您的帮助
【问题讨论】:
-
如果
@OneToManyworks 然后将其映射为这样(使用列表),并通过提供访问/修改索引 0 处的列表元素的 getter 和 setter 来简单地从客户端代码中隐藏该实现细节跨度>
标签: java spring jpa groovy spring-boot