[英]Hibernate @OneToOne self join with OR in join clause
我有一個@OneToOne
注釋,我想將其加入2個可能的列中。 我知道如何使用普通的SQL查詢來執行此操作,但是我不知道如何使用休眠注釋進行操作。
以下實體:
@Entity
public class Foo {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
private int id;
@OneToOne
@JoinColumn(name = "cancelRecord")
private Foo cancelRecord;
private String externalId;
private String externalCancellationId;
}
和對應的數據庫表:
create table Foo(
id int identity(1,1) not null primary key, --primary key
cancelRecord int,
externalId varchar(100),
externalCancellationId varchar(100)
)
到目前為止, cancelRecord
僅連接到該列。 現在,我希望它加入cancelRecord
或externalCancellationId
。 一個有效的SQL查詢將是:
SELECT f.*
FROM Foo f
INNER JOIN Foo fo
ON (f.cancelRecord = fo.id
OR f.externalCancellationId = fo.externalId)
關於此查詢的關鍵部分是join子句中的OR
(f.cancelRecord = fo.id **OR** f.externalCancellationId = fo.externalId)
。
我假設使用@JoinColumn
無法做到這一點,並且我需要以某種方式依賴@JoinFormula
。
這個假設正確嗎? 如果是這樣,我是否只需要將上述查詢復制為@JoinFormula
?
我試圖用這個@JoinFoluma
:
@OneToOne
@JoinFormula(value = "SELECT f.*
FROM Foo f
INNER JOIN Foo fo
ON (f.cancelRecord = fo.id
OR f.externalCancellationId = fo.externalId)")
private Foo cancelRecord;
加載spring上下文時,這將導致NullPointerException
:
Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'sessionFactory' defined in class path resource [spring/test-database.xml]: Invocation of init method failed; nested exception is java.lang.NullPointerException
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1589)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.doCreateBean(AbstractAutowireCapableBeanFactory.java:554)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:483)
at org.springframework.beans.factory.support.AbstractBeanFactory$1.getObject(AbstractBeanFactory.java:306)
at org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:230)
at org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:302)
at org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:197)
at org.springframework.beans.factory.support.BeanDefinitionValueResolver.resolveReference(BeanDefinitionValueResolver.java:351)
... 43 common frames omitted
Caused by: java.lang.NullPointerException: null
at org.hibernate.cfg.AnnotationBinder.bindOneToOne(AnnotationBinder.java:3185)
at org.hibernate.cfg.AnnotationBinder.processElementAnnotations(AnnotationBinder.java:1798)
at org.hibernate.cfg.AnnotationBinder.processIdPropertiesIfNotAlready(AnnotationBinder.java:961)
at org.hibernate.cfg.AnnotationBinder.bindClass(AnnotationBinder.java:788)
at org.hibernate.boot.model.source.internal.annotations.AnnotationMetadataSourceProcessorImpl.processEntityHierarchies(AnnotationMetadataSourceProcessorImpl.java:250)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess$1.processEntityHierarchies(MetadataBuildingProcess.java:231)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.complete(MetadataBuildingProcess.java:274)
at org.hibernate.boot.model.process.spi.MetadataBuildingProcess.build(MetadataBuildingProcess.java:84)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:474)
at org.hibernate.boot.internal.MetadataBuilderImpl.build(MetadataBuilderImpl.java:85)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:689)
at org.hibernate.cfg.Configuration.buildSessionFactory(Configuration.java:724)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.buildSessionFactory(LocalSessionFactoryBean.java:511)
at org.springframework.orm.hibernate5.LocalSessionFactoryBean.afterPropertiesSet(LocalSessionFactoryBean.java:495)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1648)
at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1585)
... 50 common frames omitted
編輯:
這個問題解決了異常,但可悲的是,它再次以AND
而不是OR
。
由於@JoinColumn
或@JoinFormula
用於確定外鍵列值,因此該方法不起作用,因此它們不適用於多個列。
如果定義多個@JoinColumn
或@JoinFormula
,則ON關系將使用AND
而不是OR
。
在您的情況下,由於您可能只想讀取此關聯,而不是使用Hibernate進行設置,因此最好使用SQL查詢。
您可以使用多個@JoinColumn
批注。 請參閱以下示例:
@OneToOne
@JoinColumns(
{
@JoinColumn(updatable=false,insertable=false, name="cancelRecord", referencedColumnName="cancelRecord"),
@JoinColumn(updatable=false,insertable=false, name="other", referencedColumnName="other")
}
)
private Foo cancelRecord;
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.