【问题标题】:JPA: How to exclude certain fields from loading from database tableJPA:如何从数据库表中排除某些字段
【发布时间】:2013-09-26 18:18:30
【问题描述】:

我有一个 User 类,它为我的 Web 应用程序中的身份验证用户保存电子邮件地址和密码。该用户通过 JPA / Eclipselink 映射到数据库。

我的问题是,如何防止 JPA 从数据库中加载密码字段?由于我将在我的网络应用程序中访问用户对象,因此我对将密码发送到浏览器的安全性感到不舒服。

有什么方法可以防止在 JPA / EclipseLink 中加载该字段?声明字段瞬态不是一个选项,因为我想在用户对象上调用 persist() 时将其存储在数据库中。

谢谢, 弗雷德麦迪逊

【问题讨论】:

  • 使用 JPA 在服务器内存中加载它和将其发送到浏览器之间存在巨大差异。您应该修复的是您发送到浏览器的数据,而不是您使用 JPA 加载的数据。因此,JPA 不适合查看。看看你是如何向浏览器发送数据的。

标签: jpa eclipselink


【解决方案1】:

JB Nizet 有一个有效的观点。在 Http 响应中检索和序列化它是两个独立的问题。

我不确定您使用什么来序列化您的数据。如果这是一个 REST API,请考虑 Jackson 的 @JsonIgnore 注释或 Eclipselink MOXy 的 @XmlTransient 等效项。如果这使用 Java EL(facelets、jsps),您应该能够只选择感兴趣的 bean 属性。

如果您确实必须在检索期间执行此操作,请考虑 JPQL 的/Criteria API 的构造函数功能。确保对象具有接受指定参数的构造函数,并记住,如果以这种方式检索它,它将不会在持久性上下文中进行管理。

SELECT NEW my.package.User(u.id, u.name, u.etc) FROM User u

或者,考虑@PostLoad 生命周期回调。

@PostLoad
private void postLoad() {
    this.password = null;
}

最后,情况可能并非如此,但我想强调密码不应该以明文形式存储的概念。我之所以提到这一点,是因为返回使用安全算法(bCrypt、多次迭代 SHA-512 等)的散列加盐密码并不是什么大不了的事(但仍然不理想)。

【讨论】:

  • 感谢您的详细回答。因为我使用 Jackson API,我想我会用@JsonIgnore 试试。排除密码和其他一些字段似乎很舒服。但是,由于这是通过注释完成的,因此我无法动态更改不同用例的行为。所以 postLoad() 似乎是一个选择。
【解决方案2】:

我也有类似的问题。但就我而言,我在 Entity 类中有许多 @OneToMany 关系,其中一些是 EAGER。当我查询这个实体时,它会加载所有这些,尽管对于 Web 服务我只需要其中的一些。 我试过元组查询。但这不是解决方案,因为要获得所需的 OneToMany 关系,我必须加入并获取主查询的许多重复行。它使结果更加沉重,而不是经济。

【讨论】:

    猜你喜欢
    • 2020-12-09
    • 1970-01-01
    • 1970-01-01
    • 2017-10-02
    • 2019-11-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多