如何使用JPA规范中的另一个共同实体连接两个实体?

3

我有一个简单的数据模型,包含三个元素:Principal(用户),以及他的设置和个人资料数据。UserSetting和UserProfile都与Principal相关联,但Principal与它们都没有关联(单向)。

UserProfile ----> Principal <---- UserSettings

以下是实体列表(仅显示与问题相关的字段):
@Entity
public class Principal {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;

    private boolean enabled; 
}

@Entity
public class UserProfile {
    @Id
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;

    @OneToOne(fetch = FetchType.LAZY) 
    private Principal principal;
}

@Entity
public class UserSettings{
    @Id 
    @GeneratedValue(strategy = GenerationType.AUTO) 
    private Long id;

    @OneToOne(fetch = FetchType.LAZY) 
    private Principal principal;

    private boolean isHidden;
}

以下是一个可用的JPA查询,它连接表并提取所有正确的数据:

@Query( "SELECT DISTINCT(userProfile) " +
    "FROM UserProfile userProfile " +
    "LEFT JOIN FETCH userProfile.principal AS principal " +
    "WHERE principal.enabled = :enabled " +
    "AND principal.id IN ( " +
        "SELECT userSettings.principal.id " +
        "FROM UserSettings userSettings " +
        "WHERE userSettings.isHidden = :hidden)")

有没有一种方法可以创建JPA规范来实现以下功能(请记住Principal没有对UserSettings或UserProfile的引用):

a)过滤掉未启用的Principal的用户资料

WHERE principal.enabled = :enabled
b) 过滤掉通过用户设置选择隐藏的用户资料
AND principal.id IN (
    SELECT userSettings.principal.id
    FROM UserSettings userSettings
    WHERE userSettings.isHidden = :hidden
)
1个回答

1
如果是我,我会在UserProfileUserSettings之间创建一个双向的@OneToOne关系。

转储 - 有趣的是你这么说,我实际上正在放弃双向关系,因为在双向OneToOne上使用fetch = FetchType.LAZY不起作用。花了一整天的时间试图强制它不获取OneToOne,尝试了JoinColum、JoinTable、mappedBy等方法,除了拥有单向关系之外,没有什么办法可行。目前正在为我的问题寻找解决方案,这肯定是可行的,只是我对CriteriaBuilder/Specification查询方式不太熟悉,所以有点具有挑战性。 - SergeyB
嗯,你一定是在 J2EE 应用服务器之外运行。如果是这样,你必须在 JPA 提供程序中启用编织。在 J2EE AS 中,默认情况下已启用编织。 - Flying Dumpling
请看这篇帖子,它描述了我遇到的相同问题:https://dev59.com/-1vUa4cB1Zd3GeqPuIPT - SergeyB
这两个答案非常好。只需确保您已启用运行时织入,就可以开始了。 - Flying Dumpling

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接