关于jpa:@Transient批注,@ org.springframework.data.annotation.Transient批注,临时关键字和密码存储

@Transient annotation, @org.springframework.data.annotation.Transient annotation, transient keyword and password storing

目前,我正在学习Spring框架,主要关注它的安全模块。我看过一些有关注册和登录的指南。我在User类的密码字段上看到了瞬态关键字或@Transient批注的常见用法。

我的虚拟应用程序正在使用Spring Boot + Spring MVC + Spring Security + MySQL。

我知道

Java's transient keyword is used to denote that a field is not to be serialized.

JPA的@Transient注释...

...specifies that the property or field is not persistent. It is used to annotate a property or field of an entity class, mapped superclass, or embeddable class.

以及org.springframework.data.annotation的@Transient注释...

Marks a field to be transient for the mapping framework. Thus the property will not be persisted and not further inspected by the mapping framework.

在我的MySQL数据库中,我有spring_demo模式,该模式具有3个表:

1
2
3
4
5
6
7
+-----------------------+
| Tables_in_spring_demo |
+-----------------------+
| role                  |
| user                  |
| user_role             |
+-----------------------+

当我在User类的密码字段中使用transient关键字时,它将不会存储在MySQL数据库中。 (例如:test01)

1
2
3
4
5
6
7
mysql> select * from user;
+----+--------+------------------+----------+
| id | active | email            | username |
+----+--------+------------------+----------+
|  1 |      1 | [email protected] | test01   |
+----+--------+------------------+----------+
1 row in set (0,00 sec)

当我在User类的密码字段上使用javax.persistence @Transient批注时,它也不会存储在MySQL数据库中。 (例如:test02)

但是...当我在User类的密码字段上使用org.springframework.data.annotation @Transient批注时,它确实存储在MySQL数据库中。 (例如:test03)为什么?

1
2
3
4
5
6
7
8
mysql> select * from user;
+----+--------+------------------+----------+--------------------------------------------------------------+
| id | active | email            | username | password                                                     |
+----+--------+------------------+----------+--------------------------------------------------------------+
|  1 |      1 | [email protected] | test02   |                                                              |
|  2 |      1 | [email protected] | test03   | $2a$10$UbvmdhfcKxSNr/I4CjOLtOkKGX/j4/xQfFrv3FizxwEVk6D9sAoO  |
+----+--------+------------------+----------+--------------------------------------------------------------+
2 rows in set (0,00 sec)

我的主要问题是,当我使用基于spring.data的@Transient批注时,密码字段仍然存在。为什么?为什么我应该在密码字段上使用任何@Transient注释?

感谢您的指导和事先帮助!


在Spring框架内,您可以使用Mapping Framework将一种形式转换为另一种形式。假设您的spring java服务器端应用程序需要以JSON格式将用户信息发送到客户端(网页,移动应用程序)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
@Entity
public class User {

@Id
private long id;

@Column(name ="username")
private String username;

@Column(name ="email")
private String email;

@Column(name ="password")
private String password;

}

现在要将这个Java实体对象映射为JSON格式,您可以使用映射框架(例如jackson:com.fasterxml.jackson.databind.ObjectMapper),也可以手动进行。

将用户2对象转换为JSON时将获得的JSON格式输出为:

1
2
3
4
5
6
{
  "id": 2,
  "email":"[email protected]",
  "username":"test03",
  "password":"$2a$10$UbvmdhfcKxSNr/I4CjOLtOkKGX/j4/xQfFrv3FizxwEVk6D9sAoO"
}

现在,如果您添加了:

1
2
3
@org.springframework.data.annotation.Transient
@Column(name ="password")
private String password;

然后使用Mapping Framwwork再次为用户2实体生成JSON:

1
2
3
4
5
{
  "id": 2,
  "email":"[email protected]",
  "username":"test03",
}

请注意,JSON输出中缺少密码字段。那是因为@org.springframework.data.annotation.Transient专门向spring框架指出,从Java Object转换为JSON时,您正在使用的Object Mapper不应包含此值。

还要注意,如果您尝试将上述实体持久化到数据库中,它将仍然将其保存到数据库中,因为@org.springframework.data.annotation.Transient仅适用于对象映射框架,不适用于JPA。

因此,回顾一下:

transient is for all serializations (over the wire, saving to disk, saving to db)
javax.persistence.Transient is specifically for JPA DB serialization
@org.springframework.data.annotation.Transient is for ObjectMapping Framework serializations used within Spring