Ger*_*phy 5 java json annotations hibernate
我看到了几个类似的问题,但没有一个对我有用的答案。我正在努力将现有项目转换为使用 Hibernate。我使用 Mysql 作为数据库。我有一堂这样的课:
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;
@ManyToOne
@JoinColumn(name = "group_id_user")
private Group group;
@Column(name = "name")
private String name;
...
// getters and setters....
}
Run Code Online (Sandbox Code Playgroud)
和这样的类:
@Entity
@Table(name = "group")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "group_id")
private Long groupId;
@Column(name="group_name")
private String groupName;
...
// getters and setters....
}
Run Code Online (Sandbox Code Playgroud)
User当我从数据库中获取项目时,我将其转换为 JSON 并最终得到以下格式的结果:
{
"user": {
"userId": 1,
"group": {
"groupId": 3,
"groupName": "Group Three",
},
"name": "John Doe",
}
}
Run Code Online (Sandbox Code Playgroud)
就我而言,该Group对象实际上比本示例中的要大得多,并且还包含对另一个表的引用(即Group有一个SomeOtherClass对象)。我想最终得到如下所示的结果:
{
"user": {
"userId": 1,
"groupId": 3,
"name": "John Doe",
}
}
Run Code Online (Sandbox Code Playgroud)
有没有办法只获取 JSON 响应中的 groupId 而不是整个Group对象?
我尝试将 FetchType.Lazy 添加到我的 User 类中
@ManyToOne(fetch = FetchType.LAZY)
@JoinColumn(name = "group_id_user")
private Group group;
Run Code Online (Sandbox Code Playgroud)
但是当我尝试将User对象转换为 Json 时,出现以下错误:
error: Errorjava.lang.UnsupportedOperationException: Attempted to serialize java.lang.Class: org.hibernate.proxy.HibernateProxy. Forgot to register a type adapter?
Run Code Online (Sandbox Code Playgroud)
我发现这个答案消除了错误,但是 JSON 对象与我添加FetchType.LAZY. 看起来像是以某种方式转换为 JSON 添加了被FetchType.LAZY忽略的值。
我正在使用转换为 JSON,如下所示:
GsonBuilder b = new GsonBuilder();
Gson gson = b.create();
//b.registerTypeAdapterFactory(HibernateProxyTypeAdapter.FACTORY);
com.google.gson.JsonArray jsonArray = gson.toJsonTree(out).getAsJsonArray();
Run Code Online (Sandbox Code Playgroud)
小智 5
如果我错了,请纠正我,因为我是冬眠新手。根据我迄今为止的经验,是的,可以仅发送对象 ID,而不是发送整个对象详细信息作为响应。通过使用@JsonIdentityReference并在此处@JsonIdentityInfo查找文档
下面是对我有用的示例代码:
团体课
@Entity
@Table(name = "group")
public class Group {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "group_id")
private Long groupId;
@Column(name="group_name")
private String groupName;
...
// getters and setters....
}
Run Code Online (Sandbox Code Playgroud)
用户等级
@Entity
@Table(name = "user")
public class User {
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;
@ManyToOne
@JsonIdentityInfo(generator = ObjectIdGenerators.PropertyGenerator.class, property = "group_id")
@JsonIdentityReference(alwaysAsId = true)
@JoinColumn(name = "group_id_user")
private Group group;
...
// getters and setters....
}
Run Code Online (Sandbox Code Playgroud)
结果是
{ "userId": 1, "group": 1, "name": "示例用户" }
我使用下面的代码来转换 JSON
ObjectMapper mapper = new ObjectMapper();
try {
json = mapper.writeValue(user);
} catch (JsonProcessingException e) {
e.printStackTrace();
}
Run Code Online (Sandbox Code Playgroud)
我在这里找到了我的问题的解决方案
选项1:(来自@JBNizet的评论)
创建代表 API 输出的类 (DTO),将实体转换为这些 DTO 类的实例,并使用 Gson 将 DTO 序列化为 JSON。好的 REST 框架会自动为您完成最后一部分。
对于此示例,您可以创建一个如下所示的 UserItem 类:
public class UserItem {
private Long userId;
private Long groupId;
private String name;
...
// getters and setters....
}
Run Code Online (Sandbox Code Playgroud)
然后您需要一个将 User 实体转换为 UserItem 的方法:
public UserItem UserToUserItem(User user) {
UserItem userItem = new UserItem();
userItem.setUserId(user.getUserId());
userItem.setGroupId(user.getGroup().getGroupId());
userItem.setName(user.getName());
return userItem;
}
Run Code Online (Sandbox Code Playgroud)
在您的响应中使用 userItem。
选项2:
更新:将选项 2 更新为有效的选项
如果您不想为每个实体类编写 DTO,因为(如本示例)唯一需要更改的字段是 groupId 的 Group 对象,您可以创建一个ExclusionStrategy并使用@Expose注释,如下所示:
首先创建一个类来实现ExclusionStrategy
public class SerializeExclusionStrat implements ExclusionStrategy {
@Override
public boolean shouldSkipField(FieldAttributes fieldAttributes) {
final Expose expose = fieldAttributes.getAnnotation(Expose.class);
return expose != null && !expose.serialize();
}
@Override
public boolean shouldSkipClass(Class<?> aClass) {
return false;
}
}
@Entity
@Table(name = "user")
public class User {
Run Code Online (Sandbox Code Playgroud)
然后将@Expose注释添加到 User 类中。添加附加字段groupId将允许在查询和 json 响应中返回 groupId。只需确保用updatable=false和标记 groupId 即可insertable=false。
@Id
@GeneratedValue(strategy = GenerationType.IDENTITY)
@Column(name = "user_id")
private Long userId;
@ManyToOne
@JoinColumn(name = "group_id_user")
@Expose(serialize = false)
private Group group;
@Column(name = "group_id_user", updatable = false, insertable = false)
private Long groupId;
@Column(name = "name")
private String name;
...
// getters and setters....
}
Run Code Online (Sandbox Code Playgroud)
然后在创建Gson时设置Exclusion策略:
GsonBuilder b = new GsonBuilder();
b.serializeNulls();
b.setExclusionStrategies(new SerializeExclusionStrat());
Gson gson = b.create();
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
7954 次 |
| 最近记录: |