我有两个表:Users和User_Friend,用于显示与附加字段的关系。
CREATE TABLE public.users
(
uuid VARCHAR(36) PRIMARY KEY NOT NULL,
username VARCHAR(45) UNIQUE NOT NULL,
first_name VARCHAR(255) NOT NULL,
last_name VARCHAR(255),
middle_name VARCHAR(255)
);
CREATE TABLE public.user_friends
(
uuid VARCHAR(36) PRIMARY KEY,
user_uuid VARCHAR(36) REFERENCES public.users (uuid) NOT NULL,
friend_uuid VARCHAR(36) REFERENCES public.users (uuid) NOT NULL,
friendAddDate TIMESTAMP NOT NULL,
friendTypeId INT NOT NULL,
CONSTRAINT friend_unique UNIQUE (user_uuid, friend_uuid)
);
具有休眠注释的Java实体:
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(generator = "system-uuid", strategy = GenerationType.IDENTITY)
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true)
protected String uuid;
@Column(name = "username")
protected String username;
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<UserFriend> userFriends = new HashSet<>();
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "friendUser", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<UserFriend> userFriendOf = new HashSet<>();
}
@Entity
@Table(name = "user_friends")
@AssociationOverrides({
@AssociationOverride(name = "user",
joinColumns = @JoinColumn(name = "user_uuid")),
@AssociationOverride(name = "friendUser",
joinColumns = @JoinColumn(name = "friend_uuid")) })
public class UserFriend implements Serializable {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true)
protected String uuid;
@JsonBackReference
@ManyToOne(optional = false)
@JoinColumn(name="user_uuid")
private User user;
@JsonBackReference
@ManyToOne(optional = false)
@JoinColumn(name="user_uuid")
private User friendUser;
@Column(name = "friendadddate")
protected Date friendAddDate;
@Column(name = "friendtypeid")
protected int friendTypeId;
}
我正在尝试将反序列化为JSON时解决递归问题,我已经将@JsonManagedReference添加到User类的userFriends和userFriendOf的集合中,并将@JsonBackReference添加到UserFriend类的user和friendUser实体,现在在JSP上的JSON中我没有字段也没有friendUser也不是user。
但是在这种情况下-无需在JSON中的User类中设置Set friendsOf,我就可以使用UserFriend类的friendUser。
@Entity
@Table(name = "users")
public class User implements Serializable {
@Id
@GeneratedValue(generator = "system-uuid", strategy = GenerationType.IDENTITY)
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true)
protected String uuid;
@Column(name = "username")
protected String username;
@JsonManagedReference
@OneToMany(fetch = FetchType.LAZY, mappedBy = "user", cascade = CascadeType.ALL, orphanRemoval = true)
private Set<UserFriend> userFriends = new HashSet<>();
}
@Entity
@Table(name = "user_friends")
@AssociationOverrides({
@AssociationOverride(name = "user",
joinColumns = @JoinColumn(name = "user_uuid")),
@AssociationOverride(name = "friendUser",
joinColumns = @JoinColumn(name = "friend_uuid")) })
public class UserFriend implements Serializable {
@Id
@GeneratedValue(generator = "system-uuid")
@GenericGenerator(name = "system-uuid", strategy = "uuid2")
@Column(name = "uuid", unique = true)
protected String uuid;
@JsonBackReference
@ManyToOne(optional = false)
@JoinColumn(name="user_uuid")
private User user;
@ManyToOne(optional = false)
@JoinColumn(name="user_uuid")
private User friendUser;
@Column(name = "friendadddate")
protected Date friendAddDate;
@Column(name = "friendtypeid")
protected int friendTypeId;
}
所以我的问题是我必须做些什么才能在所有用户类集合中获得friendUser和用户?
更新进度:
我正在搜索有关我的问题的信息,并连续两天在Google中的first(second)链接-这个问题... ;-)
我仍然无法用jsonreference模式解决我的问题。我开始考虑改变数据库的体系结构。
最佳答案
我做的。再次。 StackOverFlow给我的动力比问题大:D
因此,经过每小时3天漫长的思考,我的问题几乎消失了,我几乎拒绝对json进行反序列化,并在这种情况下决定不使用json,但比起考虑类的jsonidentity,这是我的解决方案。
使用JsonIdentityInfo,Jackson每次序列化您的对象时,都会向其添加一个id(在我的情况下是uuid),这样它就不会总是扫描它。
UPDATE ASNWER(为缩短答案,我删除了答案的代码先前版本):
不幸的是,当我在不同情况下测试解决方案时,发现它仅适用于json身份的第一个版本。因此,第一次“扫描”完全像一个咒语一样工作,但是第二次扫描却得到了jsonidentity而不是对象的ID。这使我了解到,我需要自己的序列化逻辑,可以在其中控制递归深度。我写的。我只能显示自定义json serializator的骨架,因为序列化的逻辑很容易并且取决于类结构。
public class JsonUserSerializer extends JsonSerializer<User> {
@Override
public void serialize(User o, JsonGenerator jsonGen, SerializerProvider serializerProvider)
throws IOException, JsonProcessingException {
// ... logic of json generation
Field[] userClassFields = o.getClass().getDeclaredFields();
// ... logic of json generation
}
@Override
public Class<User> handledType() {
return User.class;
}
}
我在处理代码时必须解决的主要问题是字段的命名。因为是json结构,所以它是:“ name”:“ value”-在我的情况下是名称-它是fieldName。但是硬编码不是我的方法。比我已经找到解决方案来获取类的所有字段都是
o.getClass().getDeclaredFields()
,而不是按索引查找需求字段。我认为这不是最好的解决方案,但是一个小时我都没有找到其他解决方案(如果您知道其他方法,请写评论-我会为此推荐作者)。忘记显示如何使用为特定类指定的定制JsonSerialiser:
@Entity
@Table(name = "users")
@JsonSerialize(using = JsonUserSerializer.class)
public class User implements Serializable {
// a lot of fields and getter, and setters
}