【问题标题】:Can I use @Where annotation along with @ManytoOne association?我可以将@Where 注释与@ManytoOne 关联一起使用吗?
【发布时间】:2019-06-26 10:45:04
【问题描述】:

EER Diagram

我不是 Spring、JPA、Hibernate 或 MySql 方面的专家。 但是,我将 all 用于支持 RESTful 调用的 Web 服务。 我正在使用 Spring 构建商店管理应用程序后端。 我此时的实体是 StoreModel、StoreUserModel、StoreUserRoleModel 和 StoreUserAuthModel。

我已经设置了双向关系(OneToMany 和 ManyToOne) StoreModel - StoreUserAuthModel, StoreUserMode - StoreUserAuthModel 和 StoreUserRoleMode - StoreUserAuthModel。

我不想要外键约束,虽然 StoreUserAuthModel 中有外键字段 storeid、roleid 和 userid。

现在四个表都有isdeleted列来实现软删除。 我很懒惰地获取关联。但是,每当我查询关联时,我都不想要软删除的值。

我想知道是否可以在 StoreUserAuthModel 实体中使用 @Where 注释和 @ManyToOne 注释?

问题与 How to use @Where in Hibernate 不同,因为我的问题是 ManyToOne 注释,而我使用了 OneToMany 的 where 注释

@Entity
@Table(name = "store")
public class StoreModel {

    @NotBlank
    private String name;

    @NotBlank
    private String address;

    @NotBlank
    private String city;

    @NotBlank
    private String phone;


    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "storeid", foreignKey = @ForeignKey(name="none", value = ConstraintMode.NO_CONSTRAINT ))
    @Where(clause="isdeleted = 0")
    private List<StoreUserAuthModel> authList = new ArrayList<StoreUserAuthModel>();


    ...
}

@Entity
@Table(name = "storerole")
public class StoreRoleModel {

    @NotBlank
    private String name;

    @NotBlank
    private Integer rolehierarchy;

    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "roleid", foreignKey = @ForeignKey(name="none", value = ConstraintMode.NO_CONSTRAINT ))
    @Where(clause="isdeleted = 0")
    private List<StoreUserAuthModel> authList = new ArrayList<StoreUserAuthModel>();

    ...


}

@Entity
@Table(name = "storeuser")
public class StoreUserModel{

    @NotBlank
    @Column(unique = true)
    private String username;

    @Email
    @Column(unique = true)
    private String useremail;

    @JsonIgnore
    @OneToMany(fetch = FetchType.LAZY)
    @JoinColumn(name = "userid", foreignKey = @ForeignKey(name="none", value = ConstraintMode.NO_CONSTRAINT ))
    @Where(clause="isdeleted = 0")
    List<StoreUserAuthModel> userAuthList = new ArrayList<StoreUserAuthModel>();

    ...

}

@Entity
@Table(name = "storeuserauth", 
        uniqueConstraints = @UniqueConstraint(columnNames = {"storeid", "roleid", "userid"}))
public class StoreUserAuthModel {

    @NotNull
    Long storeid;

    @NotNull
    Long roleid;

    @NotNull
    Long userid;

    // Using @where to filter out the soft deleted storeuser
    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="userid", foreignKey = @ForeignKey(name="none",  value = ConstraintMode.NO_CONSTRAINT ),insertable = false, updatable = false )
    @Where(clause="isdeleted = 0")
    private StoreUserModel storeuser;

    // Using @where to filter out the soft deleted store
    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="storeid", foreignKey = @ForeignKey(name="none",  value = ConstraintMode.NO_CONSTRAINT ),insertable = false, updatable = false )
    @Where(clause="isdeleted = 0")
    private StoreModel store;

    // Using @where to filter out the soft deleted role
    @JsonIgnore
    @ManyToOne(fetch = FetchType.LAZY)
    @JoinColumn(name="roleid", foreignKey = @ForeignKey(name="none",  value = ConstraintMode.NO_CONSTRAINT ),insertable = false, updatable = false )
    @Where(clause="isdeleted = 0")
    private StoreRoleModel role;

    ...


}


// In the controller, Following code shows how I plan to use

    Optional<StoreUserModel> aUser = storeUserRepository.findByUseremailAndIsdeleted(zUserMail), 0);
    if(aUser.isPresent()) {
        // The user was found!!!

        // Testing...
        // Getting the User Auth List (that will filter out the soft deleted auths)
        List<StoreUserAuthModel> authList = aUser.get().getUserAuthList();
        for(StoreUserAuthModel auth :authList) {
            StoreModel store = auth.getStore();
            // here both soft deleted store as well as normal stores are shown.
            // ie where clause  on  store relation is not working!!

            logger.debug("Store is "+store.getName());
        }


    }

...

现在与 id 匹配的所有商店行都在列表中。 预期的结果也应该适用于 where 子句

我为 hibernate 5.3.9 开启了日志记录 触发选择查询时没有where子句

【问题讨论】:

  • 我已经通过搜索互联网阅读了“Where”注释以及“OneToMany”的使用。我也想用“ManyToOne”注释做类似的任务。 hibernate在生成选择查询时似乎没有使用“Where”注释
  • 您为什么要这样做?因为您已经可以排除这些实体将查询
  • 假设我有商店用户登录。验证他的凭据后,我想检查身份验证信息。我不想获取商店用户的软删除身份验证信息。我不是 Spring 的 JPA 专家。如果您指出正确的信息,我将不胜感激,@SimonMartinelli
  • 我只能在 StoreUserAuthModel 上看到 toOne 关系。因此,如果您想在没有软删除的情况下获取 StoreUserAuthModel,您可以在类级别设置 @Where。这就是你想要的吗?

标签: mysql spring hibernate jpa bidirectional


【解决方案1】:

@Where 注释对 ToOne 关系没有影响。但是,您可以在实体上使用@Where,而不是将@Where 添加到引用中:

@Where(clause="isdeleted = 0")
@Entity
@Table(name = "storerole")
public class StoreRoleModel {

这样,Hibernate 将不会加载 StoreRoleModel 的已删除实体。

【讨论】:

    猜你喜欢
    • 2020-01-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-10-21
    • 2012-12-31
    • 2018-11-05
    • 2021-03-14
    相关资源
    最近更新 更多