gpt4 book ai didi

hibernate - JPA 标准 : downcast root to multiple entity subclasses and filter by the same linked entity natural id

转载 作者:行者123 更新时间:2023-12-04 01:46:47 25 4
gpt4 key购买 nike

鉴于我有 4 个表:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class SourceEvent {
@Id
private Long id;
}

@Entity
@PrimaryKeyJoinColumn(name = "SOURCE_EVENT_ID")
public class PrimaryEvent extends SourceEvent {
@ManyToOne
private Account account;
}

@Entity
@PrimaryKeyJoinColumn(name = "SOURCE_EVENT_ID")
public class SecondaryEvent extends SourceEvent {
@ManyToOne
private Account account;
}

@Entity
public class Account {
@Id
private Long id;

@NaturalId
@Column(name = "ACCOUNT_NUMBER", unique = true, nullable = false)
private long accountNumber;
}

如您所见, SourceEventPrimaryEvent 的父级和 SecondaryEvent并且两个事件都指向 Account .

我想过滤 SourceEvent来自 Account的帐号使用 JPA Criteria API。

我把这个放在一起:
final class Filter {

private Long accountNumber;

Specification<SourceEvent> toSpecification() {
return (Root<SourceEvent> root, CriteriaQuery query, CriteriaBuilder cb) -> {
return cb.or(
cb.equal(cb.treat(root, PrimaryEvent.class).get("account").get("accountNumber"), accountNumber),
cb.equal(cb.treat(root, SecondaryEvent.class).get("account").get("accountNumber"), accountNumber)
);
};
}
}

我在哪里使用 treat运营商从 SourceEvent 向下转型至 PrimaryEventSecondaryEvent我把两者都相等 Predicate转至 cb.or(...)
当我打电话时 sourceEventRepository.findAll(filter.toSpecification()) ,
sourceEventRepository是:
public interface SourceEventRepository extends JpaSpecificationExecutor<SourceEvent>, JpaRepository<SourceEvent, Long> {}

然后我得到以下 Hibernate 生成的 SQL:
...
from
source_event sourceeven0_
inner join
primary_event sourceeven0_1_
on sourceeven0_.id=sourceeven0_1_.source_event_id
inner join
secondary_event sourceeven0_2_
on sourceeven0_.id=sourceeven0_2_.source_event_id
cross join
account account1_
where
sourceeven0_1_.account_id=account1_.id
and (
account1_.account_number=123
or account1_.account_number=123
)

什么对我不起作用,因为它不包括 SecondaryEvent s 具有给定的帐号。

如何使它工作?

最佳答案

我们最近遇到了这个问题,并通过更改实体之一的变量名称找到了一种解决方法。

然后我们像向下转型一样强制左外连接。

根据您的用例:

@Entity
@Inheritance(strategy = InheritanceType.JOINED)
public class SourceEvent {
@Id
private Long id;
}

@Entity
@PrimaryKeyJoinColumn(name = "SOURCE_EVENT_ID")
public class PrimaryEvent extends SourceEvent {
@ManyToOne
private Account account;
}

@Entity
@PrimaryKeyJoinColumn(name = "SOURCE_EVENT_ID")
public class SecondaryEvent extends SourceEvent {
@ManyToOne
private Account account1;
}

@Entity
public class Account {
@Id
private Long id;

@NaturalId
@Column(name = "ACCOUNT_NUMBER", unique = true, nullable = false)
private long accountNumber;


询问:
final class Filter {

private Long accountNumber;

Specification<SourceEvent> toSpecification() {
return (Root<SourceEvent> root, CriteriaQuery query, CriteriaBuilder cb) -> {
Root<PrimaryEvent> primaryEventRoot = cb.treat(root, PrimaryEvent.class);
Join<PrimaryEvent, Account> primaryEvent = primaryEventRoot.join(PrimaryEvent_.account, JoinType.LEFT);

Root<SecondaryEvent> secondaryEventRoot = cb.treat(root, SecondaryEvent.class);
Join<SecondaryEvent, Account> secondaryEvent = secondaryEventRoot.join(SecondaryEvent_.account1, , JoinType.LEFT);
return cb.or(
cb.equal(primaryEvent.get("accountNumber"), accountNumber),
cb.equal(secondaryEvent.get("accountNumber"), accountNumber)
);
};
}
}

关于hibernate - JPA 标准 : downcast root to multiple entity subclasses and filter by the same linked entity natural id,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54991760/

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